C++ 类变量:公共访问只读,但私有访问读/写

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() {

哎哟,现在还没用那个套接字库。我试着在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() {
    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;
    }
}