解释一些简单的代码

Explaining some simple code

本文关键字:代码 简单 解释      更新时间:2023-10-16

下面是一个考试题目:

    /* 1 */ string s1 = "FRED";
    /* 2 */ string s2 = s1;
    /* 3 */ string s3 = "DERF";
    /* 4 */ s3 = s1;

对于上面的第二行和第四行,命名该行是什么类型的语句。将它们调用string类的相同成员函数?(5分)

所以我的答案是:

  • 第2行是初始化一个新的字符串对象s2,使用copy constructor将所有成员变量从s1复制到s2。
  • 第4行也复制了从s1到s2的所有成员变量,但是它重载了assignment operator (operator=)来这样做。

因此它们都调用了两个不同的成员函数。

以上是可以接受的答案吗?有什么我可以补充的吗,我的想法是错的吗?

关于你对第4行的回答

你不能确定它是否真的使用了复制构造函数,而且它绝对不应该使用。

当你可以直接从s1复制数据到s3时,为什么要在std::string::operator=中创建一个临时对象?

你写的关于operator=的内容是正确的,但是省略了你写的关于复制构造函数的内容。new对象没有初始化,因此不应该调用构造函数。


您还应该省略关于复制所有成员变量的语句,这并不一定是真的。

当涉及到像std::string这样的对象时,作为成员的指针不会被复制,但是它们所指向的内存被复制到一个新的内存空间中(供目标对象使用)。


Post OP编辑他/她的帖子..

OP刚刚更改了他的帖子,删除了我在这篇文章的第一部分发表的评论

。第4行还使用复制构造函数将所有成员变量从s1复制到s2

。第4行调用的是复制赋值操作符,而不是复制构造函数。

在对象声明初始化时调用构造函数。第4行没有声明任何东西,所以它调用了复制赋值,即operator=。即使这个类没有重载operator=,编译器也会为您生成一个,然后调用它。所以在任何情况下,第4行都不能调用复制构造函数。

注意,如果您认为类的对象的复制赋值没有意义,您可以禁用类的operator=。要禁用它,您所需要做的就是在类的private部分声明operator=,然后不为它提供任何定义。像这样:

struct A
{
       A(A const &) {} //copy through copy-constructor is allowed
   private:
       A& operator=(A const &);//copy through copy-assignment is disallowed
};
A x
A y(x); //ok  - copy-constructor is allowed
y = x;  //error - copy-assignment is disallowed
同样,

也可以禁用:复制构造函数和复制赋值。例如,标准库已经禁用了所有流类的复制语义。

在c++ 11中,您可以显式地禁用复制语义:

struct B
{
   private:
       B(B const &) = delete;
       B& operator=(B const &) = delete;
};

Copy-semantic对于B类是禁用的,=delete的使用使其显式。它还增加了代码的可读性,并清楚地揭示了程序员的意图。