初始化列表和赋值重载(运算符=)

发布于 2025-01-07 15:15:07 字数 408 浏览 3 评论 0原文

赋值运算符的重载是否传播到初始值设定项列表?

例如,假设一个类:

class MyClass {
    private:
        std::string m_myString; //std::string overloads operator =
    public:
        MyClass(std::string myString);
}

和一个构造函数:

MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

初始化列表会计算出 std::string 上的赋值运算符重载吗?如果没有,有解决方法吗?

特别是对于海湾合作委员会。

Does the overloading of the assignment operator propagate to an initializer list?

For example, suppose a class:

class MyClass {
    private:
        std::string m_myString; //std::string overloads operator =
    public:
        MyClass(std::string myString);
}

And a constructor:

MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

Will the initializer list work out the assignment operator overload on std::string? And if not, is there a workaround?

Particularly for GCC.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

情深已缘浅 2025-01-14 15:15:07

我认为您缺少的是赋值初始化之间的区别。

让我们看一个基本类型的简单例子:

int a = 10; // Initialization
a = 1; // Assignment

上面的例子很简单,也不难理解。然而,当您进入用户定义类型时,事情就没那么简单了,因为对象是构造的。

例如,让我们看一下 std::string

std::string s1("String1"); // Initialization (constructs s1 using constructor)
std::string s2 = s1; // Initialization (constructs s2 using copy constructor)
std::string s3(s2); // Initialization (constructs s3 using copy constructor)

s1 = s2; // Assigns s2 to s1 using assignment operator

这里的关键是 operator= 在不同的上下文中意味着不同的东西。这完全取决于左侧的内容。

  std::string s1 = "Hello"; // Lhs has std::string s1, so this is initialization
  s1 = "Bob"; // Lhs has only s1, so this is assignment

初始化列表仅进行初始化(因此称为初始化列表)。

MyClass::MyClass(std::string myString)
 : m_myString(myString) // Initialization
{
}

请注意,当您在构造函数主体中调用 operator= 时,您现在正在进行赋值而不是初始化。

MyClass::MyClass(std::string myString)
{
    // m_myString(myString); <-- Error: trying to call like a function
    m_myString = myString; // Okay, but this is assignment not initialization
}

I think what you are missing is the difference between assignment and initialization.

Lets look at a simple example with a fundamental type:

int a = 10; // Initialization
a = 1; // Assignment

The above example is simple and not difficult to understand. However, when you get into user-defined types, it is not as simple because objects are constructed.

For example, lets look at std::string

std::string s1("String1"); // Initialization (constructs s1 using constructor)
std::string s2 = s1; // Initialization (constructs s2 using copy constructor)
std::string s3(s2); // Initialization (constructs s3 using copy constructor)

s1 = s2; // Assigns s2 to s1 using assignment operator

The key thing here is operator= means different things in different contexts. It all depends on what is on the left hand side.

  std::string s1 = "Hello"; // Lhs has std::string s1, so this is initialization
  s1 = "Bob"; // Lhs has only s1, so this is assignment

And initializer lists do initialization only (hence the name initializer list).

MyClass::MyClass(std::string myString)
 : m_myString(myString) // Initialization
{
}

Just be aware, when you call operator= in the body of the constructor, you are now doing assignment and not initialization.

MyClass::MyClass(std::string myString)
{
    // m_myString(myString); <-- Error: trying to call like a function
    m_myString = myString; // Okay, but this is assignment not initialization
}
明月松间行 2025-01-14 15:15:07

我相信它将使用复制构造函数而不是赋值运算符。

I believe it will use the copy constructor rather than the assignment operator.

弃爱 2025-01-14 15:15:07
MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

请注意,这里有两份副本:一份用于初始化参数 myString,一份用于初始化成员 m_myString。你不想要这样。在 C++03 中,您将通过 const 引用获取参数:

MyClass::MyClass(const std::string& myString)
 : m_myString(myString)
{
}

而在 C++11 中,您将通过值获取参数,然后手动将其移动到成员中:

MyClass::MyClass(std::string myString)
 : m_myString(std::move(myString))
{
}
MyClass::MyClass(std::string myString)
 : m_myString(myString)
{
}

Note that you have two copies here: one to initialize the parameter myString, and one to initialize the member m_myString. You don't want that. In C++03, you would take the parameter by const reference:

MyClass::MyClass(const std::string& myString)
 : m_myString(myString)
{
}

And in C++11, you would take the parameter by value and then manually move it into the member:

MyClass::MyClass(std::string myString)
 : m_myString(std::move(myString))
{
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文