这是两个问题:-D。
尝试使用const时,我遇到了一些编译错误。
我想要实现的目标。
在我的类构造函数中,我传递一个指向对象的指针。我不希望对象的地址和值发生变化,因此我使用const。这是我的代码看起来像
类构造函数
A::A( const B* const example ): m_example(example) {
m_mth1_ex = m_example->method1();
m_mth2_ex = m_example->method2();
}
在类头文件中
C* const m_mth1_ex;
D* const m_mth2_ex ;
我收到的错误:
error: uninitialized member 'A::m_mth1_ex' with 'const' type 'C* const'
error: uninitialized member 'A::m_mth2_ex' with 'const' type 'D* const'
error: assignment of read-only data-member 'A::m_mth1_ex'
error: assignment of read-only data-member 'A::m_mth1_ex'
我想,因为我在构造函数中初始化这些值,这没关系,但我想我在头文件中声明它们并且const不喜欢它......
其次,B类中的方法不返回const对象吗?
最后,由于方法来自B类,它具有const值和地址,这些方法会改变吗?
答案 0 :(得分:3)
您难以理解初始化和分配。前者是好的,后者不是。
正确使用初始化:
A::A(const B* const example)
: m_example(example),
m_mth1_ex(m_example->method1()),
m_mth2_ex(m_example->method2())
{
}
(您甚至可能更喜欢使用example->method1()
将自己与成员变量的任何特定声明顺序分离。)
答案 1 :(得分:2)
您没有初始化这些值,您正在分配它们和编译器投诉,因为您无法将值分配给常量(只读)变量。您必须使用构造函数的初始化列表才能初始化类成员。例如:
A::A (const B *const example)
: m_example (example)
, m_mth1_ex (m_example->method1 ())
, m_mth2_ex (m_example->method2 ())
{
}
另外,由于成员申报的顺序很重要,你必须小心并注意初始化的顺序。基本上,如果在类m_example
之后声明m_mth1_ex
,则此代码将是未定义的行为,因为m_mth1_ex
将首先初始化,即使它出现在第二个初始化列表中。
在这个特定的例子中,写这个更安全:
A::A (const B *const example)
: m_example (example)
, m_mth1_ex (example->method1 ())
, m_mth2_ex (example->method2 ())
{
}
关于初始化列表和构造函数的一般要记住的另一个重要事项 - 如果在构造函数中抛出异常,则不调用该对象的析构函数。因此,如果您的method1 ()
和method2 ()
调用分配内存,则此代码很糟糕,因为一旦example->method2 ()
抛出,您将松开由example->method1 ()
分配的指针并且内存泄漏。除非m_mth1_ex
和m_mth2_ex
是某种智能指针(即std::unique_ptr
)。
答案 2 :(得分:0)
const
成员必须在初始化列表中初始化,因此这意味着您必须执行此操作:
A::A( const B* const example )
: m_example(example),
m_mth1_ex = m_example->method1(),
m_mth2_ex = m_example->method2()
{
}
但是,现在您已经在初始化顺序和可维护性方面打开了大量的蠕虫病毒。成员按声明的顺序初始化,无论您根据您编写的代码按什么顺序初始化它们。因此,如果在m_meth1_ex
之前声明m_example
,则会首先初始化m_meth1_ex
。
上述方法可行 - 但您的代码可能存在设计缺陷。我期待着提出更好的设计。