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

哇塞,暂时还没有在那个套接字库上工作。我正在尝试让自己多学一点 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;
}

简而言之,我的问题是如何允许从 f()内部完全访问 x,但是从其他任何地方只读访问 x,即允许 int newint = temp.x;,但是不允许 temp.x = 5;?类似于常量变量,但是可以从 f()写入..。

编辑: 我忘了提到我计划返回一个大的向量实例,使用 getX ()函数只会产生一个副本,而且它并不是真正最优的。我可以返回一个指针指向它,但这是不好的练习 iirc。

附注: 如果我只是想展示我对指针的基本知识,并询问它是否完整,那么我应该在哪里发帖呢?谢谢!

63673 次浏览

编写一个公共 getter 函数。

int getX(){ return x; }

您需要创建成员 private并提供一个 public getter 方法。

你当然可以:

class MyClass
{
int x_;


public:
int x() const { return x_; }
};

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

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


public:
decltype(v)& v() const { return v_; }
};

或 C + + 98:

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


public:
const std::vector<double>& v() const { return v_; }
};

这不会产生任何副本,它返回一个 一个 href = “ http://en.wikipedia.org/wiki/Reference _% 28C + +% 29”rel = “ noReferrer”> 参考 const

我所知道的对 c + + 类中的私有数据成员授予只读访问权的唯一方法是使用一个公共函数。在你的情况下,它会像:

int getx() const { return x; }

或者

int x() const { return x; }.

通过将数据成员设置为私有,默认情况下,该数据成员对类之外的作用域是不可见的(也就是不能访问)。本质上,类的成员对私有数据成员具有读/写访问权限(假设您没有将其指定为 const)。类的 friend可以访问私有数据成员。

在访问说明符上引用 给你和/或任何 C + + 的好书

但 tem.x = 5; 不允许?

这在发布的代码片段中是不允许的,因为它以任何方式声明为 二等兵,并且只能在类作用域中访问。

这里要求访问

Cout < < tem.x < endl;

但这里不是为了..

Int myint = temp.x;

这听起来很矛盾。

您必须将其保留为私有,然后创建一个函数来访问该值;

private:


int x;


public:


int X()
{
return x;
}

您可能希望模仿 C # 物业进行访问(取决于您要访问的内容、预期的环境等等)。

class Foo
{
private:
int bar;


public:
__declspec( property( get = Getter ) ) int Bar;


void Getter() const
{
return bar;
}
}

虽然我认为返回 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
}
};

temp.x在类中似乎是读写 int,但在 main中是只读 int

这可能是你想要的。

如果您想要一个只读变量,但又不希望客户端必须改变访问它的方式,那么可以尝试下面这个模板类:

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! 请记住,您还需要添加位运算符和一元运算符

有一种使用成员变量的方法,但这可能不是明智的方法。

具有一个可写的私有成员,以及一个常量引用公共成员变量,该变量使自己的类的成员别名。

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.
}

它更像 get方法,但更短。

常量指针很简单,应该适用于所有可以使指针指向的类型。

正如在其他答案中提到的,您可以为类成员创建只读功能,方法是将其设置为私有并定义 getter 函数,但不定义 setter。但是这对于每个班级成员来说都是一项繁重的工作。

还可以使用宏自动生成 getter 函数:

#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;
}
}