C++ 类变量:公共访问只读,但私有访问读/写
哎哟,现在还没用那个套接字库。我试着在C++中多教自己一点。< /P> 对于类,有没有一种方法可以使变量对公共是只读的,但在私有访问时是读+写的?e、 g.类似这样的情况:C++ 类变量:公共访问只读,但私有访问读/写,c++,access-modifiers,C++,Access Modifiers,哎哟,现在还没用那个套接字库。我试着在C++中多教自己一点。< /P> 对于类,有没有一种方法可以使变量对公共是只读的,但在私有访问时是读+写的?e、 g.类似这样的情况: class myClass { private: int x; // this could be any type, hypothetically public: void f() { x = 10; // this is OK } } int main() {
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;
}
class-myClass{
私人:
int x;//假设这可以是任何类型
公众:
void f(){
x=10;//这没问题
}
}
int main(){
我的班级温度;
//我想要这个,但私下说:这是不允许的
无法编写公共getter函数
int getX(){ return x; }
您需要将成员设置为私有
,并提供一个公共
getter方法。当然,您可以:
class MyClass
{
int x_;
public:
int x() const { return x_; }
};
如果不想复制(对于整数,没有开销),请执行以下操作:
class MyClass
{
std::vector<double> v_;
public:
decltype(v)& v() const { return v_; }
};
class-MyClass
{
std::向量v_;
公众:
decltype(v)&v()常量{return v_;}
};
或使用C++98:
class MyClass
{
std::vector<double> v_;
public:
const std::vector<double>& v() const { return v_; }
};
class-MyClass
{
std::向量v_;
公众:
常量std::vector&v()常量{return v_;}
};
这不做任何拷贝。它返回一个.
< p>我知道在C++类中授予只读访问私有数据成员的唯一方式是具有公共函数。在这种情况下,它会像:
int getx()常量{return x;}
或
intx()常量{return x;}
通过将数据成员设置为私有,默认情况下会使其对类外的作用域不可见(也称为无访问)。本质上,类的成员对私有数据成员具有读/写访问权限(假设未将其指定为const
)类的。friend
s可以访问私有数据成员
请参阅和/或任何访问说明符
但温度x=5;不允许
这在发布的代码段中是不允许的,因为它无论如何声明为私有的,并且只能在类作用域中访问
这里有你的要求
cout您必须将其保留为私有,然后创建一个函数来访问该值
private:
int x;
public:
int X()
{
return x;
}
您可能希望模仿C#进行访问(取决于您的目的、预期环境等)
虽然我认为返回const T&
的getter函数是更好的解决方案,但您几乎可以获得所需的语法:
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
}
};
class-myClass{
私人:
int x;//注意:与公共只读接口不同的名称
公众:
void f(){
x_=10;//注意私有变量的使用
}
const int&x;
myClass():x(42),x(x){}//必须具有构造函数才能初始化引用
};
int main(){
我的班级温度;
//温度x是常数,所以。。。
这可以做你想做的事
void Foo::someNonConstmethod()
{
private_bar.modifyTo( value );
}
void freeMethod()
{
readonly_bar.getSomeAttribute();
}
如果您想要一个只读变量,但不希望客户端必须更改其访问方式,请尝试以下模板类:
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;
};
模板
类只读{
谁的朋友;
公众:
内联运算符primative()常量{return x;}
模板内联布尔运算符==(常量编号&y)常量{return x==y;}
模板内联编号运算符+(常量编号&y)常量{返回x+y;}
模板内联数字运算符-(const number&y)const{return x-y;}
模板内联编号运算符*(常量编号&y)常量{return x*y;}
模板内联编号运算符/(常量编号&y)常量{返回x/y;}
模板内联编号运算符y;}
模板内联数字运算符^(const number&y)const{return x^y;}
模板内联数字运算符|(const number&y)const{return x | y;}
模板内联数字运算符&(const number&y)const{return x&y;}
模板内联数字运算符&&(const number&y)const{return x&&y;}
模板内联数字运算符| |(const number&y)const{return x | | y;}
模板内联数字运算符~()常量{return~x;}
受保护的:
模板内联编号运算符=(常量编号&y){return x=y;}
模板内联编号运算符+=(常量编号&y){return x+=y;}
模板内联编号运算符-=(常量编号&y){return x-=y;}
模板内联编号运算符*=(常量编号&y){return x*=y;}
模板内联编号运算符/=(常量编号&y){return x/=y;}
模板内联编号运算符&=(常量编号&y){返回x&=y;}
模板内联编号运算符|=(常量编号&y){返回x |=y;}
灵长类x;
};
示例用法:
class Foo {
public:
ReadOnly<Foo, int> x;
};
class-Foo{
公众:
只读x;
};
现在您可以访问Foo.x,但不能更改Foo.x!
请记住,您还需要添加位运算符和一元运算符!这只是一个开始的示例有一种使用成员变量的方法,但这可能不是最好的方法
有一个可写的私有成员和一个为自己类的成员别名的const reference public member变量
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”不会,并且可以内联,因此也不会生成更多代码。一个简单的解决方案,但没有构造函数:
class myClass {
private:
int m_x = 10; // Note: name modified from read-only reference in public interface
public:
const int& x = m_x;
};
int main() {
myClass temp;
cout << temp.x << endl; //works.
//temp.x = 57; //fails.
}
class-myClass{
私人:
int m_x=10;//注意:名称已从公共接口中的只读引用修改
公众:
常数int&x=m_x;
};
int main(){
我的班级温度;
cout如其他答案中所述,您可以通过将类成员设为私有并定义getter函数而不是setter来为其创建只读功能。但对于每个类成员来说,这需要做大量的工作
你也可以告诉我们
#define get_trick(...) get_
#define readonly(type, name) \
private: type name; \
public: type get_trick()name() {\
return name;\
}
class myClass {
readonly(int, x)
}
class myClass {
private: int x;
public: int get_x() {
return x;
}
}