6

大概不会。这是我的用例:

我有两个班A和B。

class A
{
    B *b_;
};        

class B
{
public:
    B(): b_string_("") {};

private:    
    std::string b_string_;
};

我希望 b_ 始终指向 B 对象。我希望 b_ 指向一个“空”B 对象而不是 nullptr,这样我就可以始终以定义的方式取消引用 *b_ 以获得一个空的 b_->b_string。所以我想我会创建一个全局“空 B 对象”:const B null_b。但我不能(自然)使用这个 A ctor:

A(): b_(&null_b) {};

因为 b_ 不能指向 const 变量。如果不是“空 B 对象”,则 b_ 需要指向可变的 B 对象。

使全局非常量解决了这个问题,但我想要保护 const 所以我可以保证“空对象”永远不会改变。

FWIW,这涉及一个大型项目,其中 b_ 指向另一个类中 B 对象的向量。我可以向该向量添加一个空的 B 对象,但这让我觉得很笨拙。

有没有解决我的问题的方法或模式?

4

3 回答 3

5

与其持有指向B对象的指针,不如创建一个具有虚方法的基类并存储指向该对象的指针。从它派生你的B类和一个Null_B类,但不要让方法Null_B进行修改。现在,即使您的Null_B对象不会是const,也不再重要了。

作为额外的保护层,您可以尝试修改null_b对象引发异常,以便您可以检测并找到您的逻辑错误。

于 2013-08-01T20:36:25.067 回答
3

您不能将“非常量”指针指向const对象。不幸的是,使用const_cast删除const对象的 -ness 将意味着稍后的某些代码可以尝试修改该对象。(请注意,除非原始对象是非常量,否则丢弃是未定义的行为const,因此从技术上讲,如果发生这种情况,编译器可以生成崩溃的代码。不幸的是,在很多情况下,当对象更多时它不会崩溃复杂于const char *const int []- 允许代码在覆盖您不想被写入的对象后继续执行)。

但是,由于B该类有一个b_string_私有成员,因此外部对象无法触及它,因此您可以确保b_string_ 通过一个虚函数(或多个虚函数)完成任何使用,然后从B其中派生另一个类,并且当代码尝试b_string在派生对象中进行修改时,虚函数会说“对不起,你不能这样做” 。

于 2013-08-01T19:34:43.537 回答
1

好吧,也许这完全不切实际,但是...您可以使用 B 的实例而不是指向 A 中的 B 的指针吗?这将解决潜在的 nullptr 取消引用。

编辑好,如果 B 太大,那么您可以围绕它创建一个轻量级包装器,并将该包装器的实例存储在 A 中。如果 B 为 nullptr,包装器将为您提供一些有意义的东西。

于 2013-08-01T19:32:44.503 回答