类variables:公共访问只读,但私有访问读/写
哎呀,暂时不在这个套接字库上工作。 我正在尝试用C ++来教育自己。
有了类,有没有办法让variables只读给公众,但是在私人访问时读取+写入? 比如这样的东西:
class myClass { private: int x; // this could be any type, hypothetically public: void f() { x = 10; // this is OK } } int main() { myClass temp; // I want this, but with private: it's not allowed cout << temp.x << endl; // this is what I want: // this to be allowed temp.f(); // this sets x... // this to be allowed int myint = temp.x; // this NOT to be allowed temp.x = myint; }
我的问题是,如何允许从f()
完全访问x
,而在其他任何地方只读访问,例如int newint = temp.x;
允许,但temp.x = 5;
不允许? 像一个常量variables,但可以从f()
…
编辑:我忘了提到,我打算要返回一个大的vector实例,使用getX()函数将只会做一个副本,它不是最佳的。 我可以返回一个指针,但这是不好的做法iirc。
PS:如果我只是想基本显示我对指针的了解并询问它是否完整,我会在哪里发布? 谢谢!
当然可以:
class MyClass { int x_; public: int x() const { return x_; } };
如果您不想复制(对于整数,没有开销),请执行以下操作:
class MyClass { std::vector<double> x_; public: const std::vector<double>& x() const { return x_; } };
这不会做任何副本。 它返回一个const的引用 。
虽然我认为返回const T&
的getter函数是更好的解决scheme,但您几乎可以精确地得到您要求的语法:
class myClass { private: int x_; // Note: different name than public, read-only interface public: void f() { x_ = 10; // Note use of private var } const int& x; myClass() : x_(42), x(x_) {} // must have constructor to initialize reference }; int main() { myClass temp; // temp.x is const, so ... cout << temp.x << endl; // works // temp.x = 57; // fails }
编辑 :与代理类,你可以得到正是你要求的语法:
class myClass { public: template <class T> class proxy { friend class myClass; private: T data; T operator=(const T& arg) { data = arg; return data; } public: operator const T&() const { return data; } }; proxy<int> x; // proxy<std::vector<double> > y; public: void f() { x = 10; // Note use of private var } };
temp.x
在类中似乎是一个可读写的int
,但在main
是一个只读int
。
这可能会做你想要的。
如果你想要一个只读的variables,但不希望客户端必须改变他们的访问方式,试试这个模板类:
template<typename MemberOfWhichClass, typename primative> class ReadOnly { friend MemberOfWhichClass; public: inline operator primative() const { return x; } template<typename number> inline bool operator==(const number& y) const { return x == y; } template<typename number> inline number operator+ (const number& y) const { return x + y; } template<typename number> inline number operator- (const number& y) const { return x - y; } template<typename number> inline number operator* (const number& y) const { return x * y; } template<typename number> inline number operator/ (const number& y) const { return x / y; } template<typename number> inline number operator<<(const number& y) const { return x <<y; } template<typename number> inline number operator>>(const number& y) const { return x >> y; } template<typename number> inline number operator^ (const number& y) const { return x ^ y; } template<typename number> inline number operator| (const number& y) const { return x | y; } template<typename number> inline number operator& (const number& y) const { return x & y; } template<typename number> inline number operator&&(const number& y) const { return x &&y; } template<typename number> inline number operator||(const number& y) const { return x ||y; } template<typename number> inline number operator~() const { return ~x; } protected: template<typename number> inline number operator= (const number& y) { return x = y; } template<typename number> inline number operator+=(const number& y) { return x += y; } template<typename number> inline number operator-=(const number& y) { return x -= y; } template<typename number> inline number operator*=(const number& y) { return x *= y; } template<typename number> inline number operator/=(const number& y) { return x /= y; } template<typename number> inline number operator&=(const number& y) { return x &= y; } template<typename number> inline number operator|=(const number& y) { return x |= y; } primative x; };
使用示例:
class Foo { public: ReadOnly<Foo, int> x; };
现在你可以访问Foo.x,但是你不能改变Foo.x! 请记住,您还需要添加按位和一元运算符! 这只是一个例子,让你开始
有一种方法可以用一个成员variables来实现,但可能不是这样做的明智之举。
拥有一个可写的私有成员,以及一个为其自己的类的成员别名的const引用公共成员variables。
class Foo { private: Bar private_bar; public: const Bar& readonly_bar; // must appear after private_bar // in the class definition Foo() : readonly_bar( private_bar ) { } };
这会给你你想要的。
void Foo::someNonConstmethod() { private_bar.modifyTo( value ); } void freeMethod() { readonly_bar.getSomeAttribute(); }
你可以做什么,你应该做什么是不同的事情。 我不确定我刚刚列出的方法是否受欢迎,并会通过许多代码评论。 它也不必要地增加了sizeof(Foo)(虽然只是一小部分),而一个简单的访问器“getter”不会,也可以内联,所以它也不会产生更多的代码。
你将不得不把它保密,然后做一个函数来访问这个值;
private: int x; public: int X() { return x; }
您需要将该成员设为private
并提供public
getter方法。
但是temp.x = 5; 不允许?
这是任何不允许发布的片段,因为它无论如何声明为私有的 ,只能在类作用域中访问。
这里是要求访问
cout << temp.x << endl;
但这里不是为了 –
int myint = temp.x;
这听起来很矛盾。
您可能想要模仿C# 属性进行访问(取决于您要进行的操作,预期的环境等)。
class Foo { private: int bar; public: __declspec( property( get = Getter ) ) int Bar; void Getter() const { return bar; } }
我知道在c ++类中授予对私有数据成员的只读访问权限的唯一方法是拥有一个公共函数。 在你的情况下,它会喜欢:
int getx() const { return x; }
要么
int x() const { return x; }
int x() const { return x; }
。
通过将数据成员设为私有,默认情况下使其不可见(也就是不可访问)到该类之外的范围。 实质上,类的成员具有对私有数据成员的读/写访问权限(假设你没有将其指定为const
)。 class上的friend
可以访问私人数据成员。
请参阅此处和/或任何有关访问说明符的C ++书籍 。
写一个公共的getter函数。
int getX(){ return x; }
一个简单的解决scheme,像罗布,但没有构造:
class myClass { private: int m_x=10; // Note: different name than public, read-only interface public: const int& x=m_x; }; int main() { myClass temp; // temp.x is const, so ... cout << temp.x << endl; // works // temp.x = 57; // fails }
就像一个get方法,但更短。 相互矛盾的问题…类似的东西。 范围const布尔成员; 可以节省大量的获得者,但是我不懂这个function的语言…