指针也可以指向常量空类或非常量类

Can a pointer alternatively point to a const empty class or a non-const class?

本文关键字:常量 非常 也可以 指针      更新时间:2023-10-16

可能不是。这是我的用例:

我有两个班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。但我不能(自然地)使用这个ctor:

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

因为b_不能指向常量变量。如果不是"null B对象",B_需要指向可变的B对象。

使全局非常量解决了这个问题,但我希望常量得到保护,这样我就可以保证"null对象"永远不会更改。

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

有什么方法或模式可以解决我的问题吗?

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

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

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

但是,由于B类有一个b_string_成员是私有的,因此任何外部对象都不能接触它,因此您可以确保b_string_的任何使用都是通过一个虚拟函数(或多个虚拟函数)完成的,然后从B派生另一个类,在该类中,当代码试图修改派生对象中的b_string时,虚拟函数会说"对不起,您不能这样做"。

好吧,也许这完全偏离了重点,但是。。。你能在A中使用B的实例而不是指向B的指针吗?这将解决潜在的nullptr取消引用问题。

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