c++ - 为什么 C++ 没有 const 构造函数?

标签 c++ constructor constants

(编辑:由于前面的示例存在缺陷,可能会导致一些答案/评论看起来很奇怪)

这可能有点做作,但由于缺少 const 构造函数,以下是合法的:

class Cheater
{
public:
    Cheater(int avalue) 
       : cheaterPtr(this) //conceptually odd legality in const Cheater ctor
       , value(avalue) 
    {}

    Cheater& getCheaterPtr() const {return *cheaterPtr;}
    int value;

private:
    Cheater * cheaterPtr;
};

int main()
{
    const Cheater cheater(7); //Initialize the value to 7

    cheater.value                 = 4;    //good, illegal
    cheater.getCheaterPtr().value = 4;    //oops, legal

    return 0;
}

似乎提供一个 const 构造函数在技术上与 const 方法一样简单,并且类似于 const 重载。

注意:我不是在寻找 'Image( const Data & data ) const' 而是 'const Image( const Data & data) const '

所以:

  • 为什么 C++ 中没有 const 构造函数?

这里有一些与上下文相关的 Material :

最佳答案

仅仅因为 Image 在您的虚构构造函数中是 const 并不意味着 m_data 指向的是什么。您最终可以在您的类中将“指向 const 的指针”分配给“指向非 const 的 const 指针”,这将在没有强制转换的情况下删除 const 。这显然会允许你违反不变量并且不能被允许。

据我所知,任何所需的特定常量集都可以在当前标准中准确完整地指定。

另一种看待它的方式是,const 表示该方法不会改变对象的状态。构造函数的唯一目的是将对象的状态初始化为有效(无论如何,希望 - 任何具有副作用的构造函数都应该......仔细评估)。

编辑:在 C++ 中,常量适用于两个成员,对于指针和引用,适用于被引用对象的可访问常量。 C++ 有意识地决定将这两种不同的常量分开。首先,我们是否同意这段演示差异的代码应该编译并打印出“非常量”?

#include <iostream>

struct Data
{
    void non_const() { std::cout << "non-const" << std::endl; }
};

struct Image
{
     Image(             Data & data ) : m_data( data ) {}

     void check() const { m_data.non_const(); }
     Data & m_data;
};

int main()
{
    Data data;
    const Image img(data);
    img.check();

    return 0;
}

因此,为了获得可以接受 const-ref 并将其存储为 const-ref 的行为,引用的有效声明必须更改为 const。这意味着它将是一个完全不同的类型,而不是原始类型的 const 版本(因为在 C++ 中,具有不同 const 限定的成员的两种类型被视为两种不同的类型)。因此,要么编译器必须能够执行过多的幕后魔法来来回转换这些东西,记住成员的常量性,要么它必须将其视为一个单独的类型,然后不能代替普通类型使用。

我认为您要实现的是 referencee_const 对象,这是一个仅作为单独的类存在于 C++ 中的概念(我怀疑可以通过明智地使用模板来实现,尽管我没有尝试过)。

这是一个严格的理论问题(答案:C++ 决定拆分对象和引用常量)还是您正在尝试解决一个实际实际的非人为问题?

关于c++ - 为什么 C++ 没有 const 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6936124/

相关文章:

android - 为什么对 DialogFragment 使用 newInstance 而不是构造函数?

ruby - 如何在继承类中使用重写常量

c# - 使用全局常量或枚举而不指定类名

c++ - 可以使用运算符 << 来设计我们自己的输出显示方式

c++ - 在 C++ 中从模板创建对象

c++ - 当我抛出异常时内存是否被释放?

java - 这个类的构造函数在哪里?

c - 将指向 const 类型的指针初始化为非常量类型

C 主项目中的 C++ 静态库

c++ - Windows 10 中的 SDL2 图像加载