我有一段 C++ 代码,它提供对私有成员变量的公共只读访问,如下所示:
class Client {
public:
const bool &connected = mConnected; // Provide read only access to mConnected.
private:
bool mConnected = false;
};
现在我想创建一个类,它实现 BusinessLogic 并由
Client
组成。
我上这门课:
class BusinessLogic {
public:
const bool &clientConnected = mClient.connected; // Provide read only access to mClient.connected.
private:
Client mClient;
};
mClient
应该是私有的,因为我的 BusinessLogic
类管理 mClient
,其他人不应该弄乱它。然而,暴露公共只读访问 Clients connected
成员确实很方便。我也想保持代码风格相似,所以我尝试用同样的方式来做。
我这样使用它:
int main(int argc, char *argv[]) {
BusinessLogic bl;
if (bl.clientConnected) { // <<-- Gives segmentation fault
printf("Connected.");
} else {
printf("Disconnected.");
}
}
编译得很好,但是,我在运行时遇到了分段错误。
如果我在我的
BusinessLogic
类中更改此行:
const bool &clientConnected = false; // const bool &clientConnected = mClient.connected;
一切都运行,没有运行时错误。
我认为这是因为我正在使用引用变量分配引用变量。但显然我误解了一些东西。
到底发生了什么?我以为
clientConnected
会指mConnected
中的mClient
,但事实显然并非如此?
有没有一种优雅的方法来解决这个问题?
不管这是否是一个好主意或好设计的讨论,问题在于初始化的顺序。
变量按照声明的顺序进行初始化。因此,在 BusinessLogic 中,首先初始化“clientConnected”。它是用什么来初始化的? mClient.connected。但是 mClient 尚未初始化,并且由于“connected”需要设置为“mConnected”才能安全访问,因此“clientConnected”最终指向“Client:”内存偏移处的任何垃圾: :已连接”字段。
我说过我并不是在评论这样做是否是一个好主意,但你所遇到的这个问题本身就说明了为什么它不是一个好主意。显然,您可以通过重新排序字段来修复它,但是您很容易一直遇到这样的问题,而在编译过程中却没有注意到。如果您想公开对成员变量的只读访问权限,我建议(每个)创建一个吸气剂。这将绕过必须初始化引用变量的所有问题。