这个问题试图收集每年出版的数十本不良C++书籍中的少数珍珠.
与许多其他编程语言不同,这些编程语言经常从互联网上的教程中随处获取,很少有人能够快速学习C++,而无需学习编写精良的C++书籍.这样做太复杂了.事实上,它是如此庞大和复杂,有很多非常糟糕的C++书籍.我们并不是在谈论糟糕的风格,而是体育明显的事实错误和促进糟糕的编程风格.
请编辑接受的答案,以提供高质量的书籍和近似的技能水平 - 最好 在 C++聊天室讨论您的添加后.(如果他们不同意建议,常客可能会毫不留情地撤销你的工作.)添加一篇关于你亲自阅读/受益的每本书的简短描述/描述.随意讨论质量,标题等.符合标准的书籍将被添加到列表中.由C和C++用户协会(ACCU)撰写评论的图书都有指向评论的链接.
*注意:常见问题和其他资源可以在C++标签信息和c ++ - faq中找到.
c++ c++-faq copy-constructor assignment-operator rule-of-three
所以基本上这段代码:
class A {
};
class B {
B (const B& b) {}
public:
B (){}
B (const A& a) {}
};
int main()
{
A a;
B b1(a); //OK
B b2 = a; //Error
}
Run Code Online (Sandbox Code Playgroud)
只生成一个错误B b2 = a.那个错误是
错误:'B :: B(const B&)'是私有的
除了直接转换构造函数之外,为什么还要尝试调用复制构造函数?
从错误消息中可以清楚地看到B创建了一个临时文件然后用于复制构造,但为什么呢?这个标准在哪里?
为什么 C++ 提供复制构造函数?赋值运算符可以完成相同的任务。与赋值运算符相比,复制构造函数有什么优势吗?
在c ++ primer(第5版)中,提到不允许从支持的值列表中分配std :: array.
由于右侧操作数的大小可能与左侧操作数的大小不同,因此数组类型不支持assign,并且不允许从支持的值列表中进行赋值.
下面的代码作为示例给出.
std::array<int, 10> a1 = {0,1,2,3,4,5,6,7,8,9};
std::array<int, 10> a2 = {0}; // elements all have value 0
a1 = a2; // replaces elements in a1
a2 = {0}; // error: cannot assign to an array from a braced list
Run Code Online (Sandbox Code Playgroud)
但是,当我使用c ++ 11编译器编译此代码时,它工作正常.这是现在允许还是我错过了什么?
当需要复制构造函数时,我有点不确定.例如,给定此功能:
template<class T>
T max(const T* array, int size) {
T result = array[0];
for (int i = 1; i < size; ++i) {
if (result < array[i]) {
result = array[i];
}
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
我需要该类型的复制构造函数的原因是什么T?我认为一定是因为我们以价值回报.这行T result = array[0];还需要复制构造函数吗?
我想在声明中为类分配一个值,所以我创建了这个基本类:
class A
{
public:
A &operator=(int)
{
return (*this);
}
};
Run Code Online (Sandbox Code Playgroud)
并用这个main编译它:
int main(void)
{
A x = 1;
}
Run Code Online (Sandbox Code Playgroud)
但编译器抱怨此错误消息:
no viable conversion from 'int' to 'A'
A x = 1;
^ ~
Run Code Online (Sandbox Code Playgroud)
但是当我用这个main编译时:
int main(void)
{
A x;
x = 1;
}
Run Code Online (Sandbox Code Playgroud)
一切顺利编译
为什么我的第一个主要不编译,如何更改类A以便编译?
有一个A类,有2个对象A1和A2.
现在要将A2的成员值分配给A1,我可以使用简单的A1 = A2,或者使用复制构造函数,如: -
A (A &A2)
{
this.m = A2.m;
this.n = A2.n;
}
Run Code Online (Sandbox Code Playgroud)
所以,我想知道哪一个更好,哪个选项适合,或者它们之间真的有什么区别?
这不会编译。为什么?
#include <iostream>
#include <vector>
struct test_s {
int a;
test_s& operator=(test_s &&ts) {
a = ts.a;
ts.a = 0;
return *this;
}
};
int main ()
{
std::vector<test_s> v;
test_s ss = std::move(v.front());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误:
source_file.cpp:20:10: error: call to implicitly-deleted copy constructor of 'test_s'
test_s ss = std::move(v.front());
^ ~~~~~~~~~~~~~~~~~~~~
source_file.cpp:9:13: note: copy constructor is implicitly deleted because 'test_s' has a user-declared move assignment operator
test_s& operator=(test_s &&ts) {
^
1 error generated
Run Code Online (Sandbox Code Playgroud)
是否可以从矢量移动对象(无需调用复制赋值运算符)?
#include <iostream>
using namespace std;
struct Car
{
int size = 4;
int* tires = nullptr;
Car()
{
cout << "ctor" << endl;
tires = new int[size];
}
Car(const Car& car)
{
cout << "copy ctor" << endl;
tires = new int[size];
memcpy(tires, car.tires, size*sizeof(int));
}
Car& operator= (Car& car)
{
cout << "copy assignment operator" << endl;
tires = new int[size];
memcpy(tires, car.tires, size*sizeof(int));
return *this;
}
~Car()
{
cout << "dtor" << endl;
delete tires;
}
};
int …Run Code Online (Sandbox Code Playgroud) 我写了一个简单的代码,我的问题是:为什么item_base只调用constrcut函数?应该调用item_base"copy construct function"吗?我观察到当我创建item_base2时,它调用"copy construct function",但是item_base不调用"copy"构造函数".有什么区别?
class Item_base {
public:
Item_base();
Item_base(int);
Item_base(const Item_base &base);
void operator=(const Item_base &item);
virtual ~Item_base();
};
Item_base::Item_base()
{
cout << "construct function" << endl;
}
Item_base::Item_base(int a)
{
cout << "arg construct function" << endl;
}
Item_base::Item_base(const Item_base &base)
{
cout << "copy function" << endl;
}
void Item_base::operator=(const Item_base &item)
{
cout << "= operator" << endl;
}
Item_base::~Item_base()
{
}
int main()
{
//cout << "Hello world!" << endl;
Item_base item_base = Item_base(1);//construct …Run Code Online (Sandbox Code Playgroud) 在查看同事的代码时,我发现了一个有趣的行为。他声明了一个公共操作符=,但没有定义它,但代码似乎使用了默认的复制构造函数。好奇,我尝试了一下,发现当我尝试声明而不定义复制构造函数时,类似的事情会导致编译器错误。我试过的代码示例 -
class Classy
{
public:
Classy& operator =(const Classy&); // compiles, seems to use default copy CTor
Classy(const Classy&); // compiler error
int a, b;
};
int main()
{
Classy Foo;
Classy Baz = Foo; // compiles, seems to use default copy CTor
Classy Bar(Foo); // compiler error
}
Run Code Online (Sandbox Code Playgroud)
为什么 operator= 似乎在没有相应定义的情况下工作,但复制构造函数却没有?