c++;不带构造函数的类成员初始化 有人能解释一下C++中内存分配和初始化的工作原理吗?

c++;不带构造函数的类成员初始化 有人能解释一下C++中内存分配和初始化的工作原理吗?,c++,C++,File Test.h ----------- class Test { public: Test(); void clearSet(); private: std::set<std::string> m_SetStringMember; int m_initMe; } File Test.cpp ------------- Test::Test():m_initMe(0) {} Test::c

File Test.h
-----------
class Test
{
    public:
        Test();

        void clearSet();

    private:
        std::set<std::string> m_SetStringMember;
        int m_initMe;
}

File Test.cpp
-------------

Test::Test():m_initMe(0)
{}

Test::clearSet()
{
    m_SetStringMember.clear(); 
}
文件Test.h
-----------
课堂测试
{
公众:
Test();
void clearSet();
私人:
std::set m_SetStringMember;
int m_initMe;
}
文件Test.cpp
-------------
Test::Test():m_initMe(0)
{}
测试::clearSet()
{
m_SetStringMember.clear();
}
我真正理解的是:
int
成员
m_initMe
在构造函数中正确初始化,因此在内存中具有有效地址和有效值。
但是使用
m_SetStringMember
会发生什么呢?
它必须在内存中有一个有效的地址吗?
它是否必须具有有效的默认值
std::Set()的默认构造函数设置

或者我必须在构造函数中显式设置
m_SetStringMember=std::set()

m_SetStringMember
是具有自己构造函数的类的对象。它已由其构造函数正确初始化

但是m_SetStringMember会发生什么呢? 它必须在内存中有一个有效地址吗

是的,但地址与构造函数无关。构造函数仅在编译器或堆分配器为对象提供有效地址后初始化对象

它是否必须具有有效的默认值

由std::Set()的默认构造函数设置

还是必须显式设置m_setString成员= 构造函数中的std::set()

如果你想明确的说出来,就这样做

Test::Test() : m_initMe(0), m_SetStringMember() {}

但默认情况下,同样的事情也会发生。

约翰正确帖子的另一个附录:

这些变量的初始化顺序与它们的声明顺序相同,因此,实际上,如果您希望显式,您应该这样做:

Test::Test() : m_SetStringMember(), m_initMe(0)  {}
确保初始化列表中的顺序与声明它们的顺序相匹配是一种很好的做法,您甚至可以让编译器警告您。很多时候,你的变量最终会相互依赖,从而排序


此外,如果不指定默认值,则使用类默认构造函数(如果不创建它,编译器将为您生成一个,假定它可用,即没有任何访问限制)——边注释:在创建C++类构造函数的通用策略中检查3的规则。如果变量是POD(普通的旧数据类型——ints、floats等),那么它将默认为0。

即使您不初始化
m_initMe
它也有内存(当您创建对象时),只是它有不确定的值。同样的情况也适用于
m_SetStringMember
,但是它是通过默认构造函数调用的,默认构造函数会给它一个有效的状态。因为它是在堆栈上分配的!!!如果你有一个指针,它将是垃圾。@bash.d:如果它是指针,它将不是类
std::set
的对象。对不起?如果I
std::set*m_SetStringMember必须使用
new
分配它,否则它将包含垃圾`@bash.d
std::set*
std::set
是两个不同的东西。第二种类型为“字符串集”,第一种类型为“字符串集指针”,它本身不是“字符串集”。您的断言是正确的,但超出了这里的范围,因为我们不是在讨论指针。@bash.d它与“堆栈”无关-您无法从类定义中判断将在哪里分配成员。如果动态分配
Test
实例,则其所有成员都必须包含在其中(即,不是“在堆栈上”)。请注意,给出有效地址的不是编译器。这是一个运行时活动。