C++:总是首选值初始化而不是默认初始化?[duplicate]

sczxawaw  于 2022-12-05  发布在  其他
关注(0)|答案(3)|浏览(271)

此问题在此处已有答案

C++ default initialization and value initialization: which is which, which is called when and how to reliably initialize a template-type member(2个答案)
Difference between default-initialize and value-initialize? [duplicate](2个答案)
16小时前就关门了。
如果我没理解错的话,值初始化T obj {};使用用户定义的构造函数,而默认初始化T obj;要么使用用户定义的构造函数,要么不初始化obj(即未定义)。
既然有未初始化的值通常是不好的,我们是否应该总是喜欢值初始化而不是默认初始化?是否有默认初始化实际上比值初始化更好的情况?

41zrol4v

41zrol4v1#

T obj;要么使用用户定义的构造函数,要么使obj未初始化(即未定义)。
obj在这种情况下是初始化的。此外,类类型的所有非静态成员也是默认初始化的,只有内置类型的非静态成员(指针、intchar等)保留不确定的值。这意味着无论如何都会为这些成员分配所需的内存,但是没有额外地将它们设置为任何特定值(我个人对C编程语言的类比是malloccalloc函数)。
T obj {};使用用户定义的构造函数,而默认初始化T obj;使用用户定义的构造函数或使obj未初始化
如果提供了用户定义的构造函数,则默认初始化和值初始化({})调用相同的构造函数,并具有相同的效果(取决于构造函数的实现方式)。
如果没有用户定义的默认构造函数(或者它是用default关键字定义的),也没有接受std::initializer_list参数的构造函数,那么值初始化({})确保所有非静态成员都是值初始化的,而默认初始化确保成员是默认初始化的(对于原语来说,这意味着它们的值是不确定的)。
我们是否应该总是更喜欢值初始化而不是默认初始化?
零初始化是一个额外的计算,在C++中,你不需要为你不使用的东西付费,所以如果你不需要你的类的某些部分有确定的值,你可以使用默认初始化(T obj)而不是值初始化(T obj{})来购买一些计算能力。

tvokkenx

tvokkenx2#

值初始化和默认初始化之间的一个关键区别是值初始化保证对象用默认值正确初始化,而默认初始化不提供这种保证。这意味着值初始化更安全、更可靠,因为它确保对象始终处于定义良好的状态。
值初始化和默认初始化之间的另一个区别是值初始化可以用于初始化任何类型的对象,包括内置类型、用户定义类型和抽象类型,而默认初始化只适用于非抽象类型的对象。这意味着值初始化更通用和灵活,因为它可以在更广泛的情况下使用。
总的来说,值初始化和默认初始化之间的选择取决于具体的需要和情况的要求。一般来说,值初始化是一种更安全和更可靠的初始化对象的方法,但它可能需要更多的代码,并且可能不适用于所有情况。默认初始化是一种更简单和更简洁的初始化对象的方法,但如果对象没有正确初始化,则可能导致不可预测的行为。

ht4b089n

ht4b089n3#

是的,你是正确的,用T obj {}初始化值;将始终使用用户定义的构造函数初始化对象,而默认初始化用T obj;可能会使用使用者定义的建构函式,或将对象保留为未初始化(也就是具有不确定的值)。
一般来说,避免使用未初始化的值是一个很好的做法,因为它们可能会导致程序中出现未定义的行为。因此,应尽可能使用值初始化而不是默认初始化。
但是,在一些情况下,默认初始化可能是必要的或可取的。例如,如果您正在声明一个大型对象数组,并希望使用默认构造函数初始化每个元素,则默认初始化可能比值初始化更有效,因为它不需要为每个元素调用用户定义的构造函数。在这种情况下,默认初始化可能是一种有用的优化。
默认初始化可能有用的另一种情况是,当您声明一个包含其他对象作为成员的类或结构时,您希望用它们的默认构造函数初始化成员对象。在这种情况下,默认初始化可能很有用,因为它允许您初始化成员对象,而无需在类或结构的初始化列表中显式调用它们的默认构造函数。
以下是如何以这种方式使用默认初始化的示例:

struct MyStruct {
    int a;
    std::string b;
    std::vector<double> c;
};

int main() {
    // Use default initialization to initialize the member objects
    // with their default constructors
    MyStruct s;

    // s.a will be uninitialized (i.e. indeterminate)
    // s.b will be initialized to the empty string
    // s.c will be initialized to an empty vector
}

在这个例子中,MyStruct结构包含三个成员对象-一个int、一个std::string和一个std::vector。当我们使用默认初始化声明MyStruct的示例时,int成员a将保持未初始化,而std::string成员b和std::vector成员c将使用其默认构造函数进行初始化。
总的来说,虽然默认初始化在某些情况下很有用,但通常应避免使用默认初始化,而应使用值初始化,以确保始终正确初始化对象,并避免程序中出现未定义的行为。

相关问题