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

Fur*_*ead 52 c++ access-modifiers

哎呀,暂时不在那个套接字库上工作.我正在尝试用C++教育自己一点.

对于类,有没有办法让变量只读公开,但私有访问时读取+写入?例如:

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;
}
Run Code Online (Sandbox Code Playgroud)

我的问题,浓缩,是如何允许x从内部完全访问f()但只int newint = temp.x;允许其他任何地方的只读访问,即允许但temp.x = 5;不允许?像一个const变量,但可写f()...

编辑:我忘了提到我计划返回一个大型的矢量实例,使用getX()函数只会复制它并且它不是真正的最佳.我可以返回一个指向它的指针,但这是不好的做法iirc.

PS:如果我只是想基本上展示我对指针的知识并询问它是否完整,我会在哪里发帖?谢谢!

Ale*_* C. 48

当然可以:

class MyClass
{
    int x_;

public:
    int x() const { return x_; }
};
Run Code Online (Sandbox Code Playgroud)

如果您不想复制(对于整数,没有开销),请执行以下操作:

class MyClass
{
    std::vector<double> x_;

public:
    const std::vector<double>& x() const { return x_; }
};
Run Code Online (Sandbox Code Playgroud)

这不会制作任何副本.它返回对const引用.

  • @ThomasMatthews Alexandre 只是给出了两个不同的例子。如果你有一个 int 不返回 const 引用,如果你有一个 std::vector 返回一个 const 引用。我们并不是要将第一个示例中的单个 int 存储在向量中。 (2认同)

Rob*_*obᵩ 48

虽然我认为返回的getter函数const T&是更好的解决方案,但您几乎可以准确地获得所要求的语法:

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

}
Run Code Online (Sandbox Code Playgroud)

编辑:使用代理类,您可以准确地获得您要求的语法:

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
    }
};
Run Code Online (Sandbox Code Playgroud)

temp.x似乎是一个可读写int的类,但只读intmain.


Mig*_*ons 10

一个简单的解决方案,如Rob,但没有构造函数:

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

}
Run Code Online (Sandbox Code Playgroud)

就像一个获得方法,但更短.积极的问题...类似的东西.范围const bool成员; 可以节省很多吸气剂...但我不知道有这个功能的语言...

  • 我相信这应该是这个问题的最佳答案。 (5认同)

Jon*_*han 5

这可能会做你想要的.

如果您想要一个只读变量但不希望客户端必须更改它们访问它的方式,请尝试这个模板化的类:

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;                                                                                
};      
Run Code Online (Sandbox Code Playgroud)

示例使用:

class Foo {
public:
    ReadOnly<Foo, int> x;
};
Run Code Online (Sandbox Code Playgroud)

现在您可以访问Foo.x,但您无法更改Foo.x!请记住,您还需要添加按位和一元运算符!这只是一个让你入门的例子