class MyClass
{
public:
~MyClass() {}
MyClass():x(0), y(0){} //default constructor
MyClass(int X, int Y):x(X), y(Y){} //user-defined constructor
MyClass(const MyClass& tempObj):x(tempObj.x), y(tempObj.y){} //copy constructor
private:
int x; int y;
};
int main()
{
MyClass MyObj(MyClass(1, 2)); //user-defined constructor was called.
MyClass MyObj2(MyObj); //copy constructor was called.
}
Run Code Online (Sandbox Code Playgroud)
在第一种情况下,当MyClass(1, 2)调用用户定义的构造函数并返回一个对象时,我希望MyObj调用复制构造函数.为什么它不需要为第二个实例调用复制构造函数MyClass?
这可能是一个明显答案或重复的问题.如果有,抱歉,我会删除它.
为什么不复制构造函数(如默认ctors或dtors),以便在调用派生类的复制构造函数之前调用基类的复制构造函数?对于复制构造函数和析构函数,它们分别在从base-to-derived和derived-to-base的链中被调用.为什么复制构造函数不是这种情况?例如,这段代码:
class Base {
public:
Base() : basedata(rand()) { }
Base(const Base& src) : basedata(src.basedata) {
cout << "Base::Base(const Base&)" << endl;
}
void printdata() {
cout << basedata << endl;
}
private:
int basedata;
};
class Derived : public Base {
public:
Derived() { }
Derived(const Derived& d) {
cout << "Derived::Derived(const Derived&)" << endl;
}
};
srand(time(0));
Derived d1; // basedata is initialised to rand() thanks to Base::Base()
d1.printdata(); // prints the random number
Derived d2 = …Run Code Online (Sandbox Code Playgroud) 请编写复制构造函数和赋值运算符在C++中需要执行的任务列表,以保证异常安全,避免内存泄漏等.
假设我有一个类,其中唯一的数据成员是std::string或类似的std::vector.我是否需要提供复制构造函数,析构函数和赋值运算符?
我经常遇到问题,我必须扩展编译器生成的复制构造函数.例:
class xyz;
class C
{
...
int a, b, c;
std::set<int> mySet;
xyz *some_private_ptr;
};
Run Code Online (Sandbox Code Playgroud)
假设,some_private_ptr只应在特定条件下复制.对于其他条件,应将其重置为NULL复制.所以我必须编写一个复制构造函数,如:
C::C(const C &other) :
a(other.a),
b(other.b),
c(other.c),
mySet(other.mySet)
{
if(CanCopy(other.some_private_ptr)) // matches condition
some_private_ptr = other.some_private_ptr;
else
some_private_ptr = NULL;
}
Run Code Online (Sandbox Code Playgroud)
问题是该类可能有许多数据成员,并且当我添加数据成员时,我很可能忘记更新复制构造函数.如果我能写的话,那将是非常好的.
C::C(const C &other) :
C::default_copy(other)
{
if(CanCopy(other.some_private_ptr)) // matches condition
some_private_ptr = other.some_private_ptr;
else
some_private_ptr = NULL;
}
Run Code Online (Sandbox Code Playgroud)
这将使我的代码更安全,更容易维护.不幸的是我不知道这种可能性.有没有?
我花了大量的时间来摆弄Visual Studio中的complilation错误.我已经将代码提炼到下面的小编译示例中,并在IdeOne上尝试了它并得到了同样的错误,你可以在这里看到.
我想知道为什么以下代码尝试调用B(const B&)而不是B(B&&):
#include <iostream>
using namespace std;
class A {
public:
A() : data(53) { }
A(A&& dying) : data(dying.data) { dying.data = 0; }
int data;
private:
// not implemented, this is a noncopyable class
A(const A&);
A& operator=(const A&);
};
class B : public A { };
int main() {
B binst;
char* buf = new char[sizeof(B)];
B* bptr = new (buf) B(std::move(binst));
cout << bptr->data << endl;
delete[] buf; …Run Code Online (Sandbox Code Playgroud) 例如,我想声明一个类,但我希望客户端无法使用复制构造函数(或复制赋值运算符)
以下两个都不允许使用复制构造函数:
1.
class Track
{
public:
Track(){};
~Track(){};
private:
Track(const Track&){};
};
Run Code Online (Sandbox Code Playgroud)
2.
class Track
{
public:
Track(){};
~Track(){};
Track(const Track&)=delete;
};
Run Code Online (Sandbox Code Playgroud)
其中一种方式"比其他方式更正确"还是相同?有副作用吗?
//Does not compile with both the above ways
int main()
{
Track l;
Track p(l);
}
Run Code Online (Sandbox Code Playgroud) 我明白,当我们定义类的类复制构造函数时,必须作为三个状态的规则.我还注意到复制构造函数的参数通常const如下面的代码所示:
class ABC {
public:
int a;
int b;
ABC(const ABC &other)
{
a = other.a;
b = other.b;
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是如果复制构造函数的参数不是const会发生什么:
class ABC
{
public:
int a;
int b;
ABC(ABC &other)
{
a = other.a;
b = other.b;
}
}
Run Code Online (Sandbox Code Playgroud)
我理解在某些情况下,如果复制构造函数的参数是const,那么第二个实现将失败.此外,如果复制构造函数的参数是const,则要复制的对象在此过程中不会更改其内容.但是,我注意到有些人仍然使用第二个实现而不是第一个实现.是否有任何理由认为第二种实施方式是首选的?
我的目标是将std::thread对象保留为数据成员,并在需要时对其进行初始化.
我无法执行此操作(如下面的代码中所示),因为类的复制构造函数std::thread已被删除.还有其他办法吗?
class MyClass
{
public:
MyClass():DiskJobThread(){};
~MyClass();
void DoDiskJobThread();
private:
int CopyThread(const std::wstring & Source, const std::wstring & Target);
int MoveThread(const std::wstring & Source, const std::wstring & Target);
std::thread DiskJobThread;
};
MyClass::~MyClass()
{
DiskJobThread.join();
}
void MyClass::DoDiskJobThread()
{
std::wstring Source = GetSource();
std::wstring Target = GetTarget();
int m_OperationType = GetOperationType();
if (m_OperationType == OPERATION_COPY)
{
DiskJobThread = std::thread(&MyClass::CopyThread, *this, Source, Target);
}
else if (m_OperationType == OPERATION_MOVE)
{
DiskJobThread = std::thread(&MyClass::MoveThread, *this, Source, Target);
} …Run Code Online (Sandbox Code Playgroud) 基于此代码
struct Foo
{
Foo()
{
cout << "default ctor" << endl;
}
Foo(std::initializer_list<Foo> ilist)
{
cout << "initializer list" << endl;
}
Foo(const Foo& copy)
{
cout << "copy ctor" << endl;
}
};
int main()
{
Foo a;
Foo b(a);
// This calls the copy constructor again!
//Shouldn't this call the initializer_list constructor?
Foo c{b};
_getch();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
默认ctor
复制ctor
复制ctor
在第三种情况下,我将b放入大括号初始化,它应该调用initializer_list <>构造函数.
相反,复制构造函数起带头作用.
你们有人会告诉我这是如何运作的,为什么?