c++ c++-faq copy-constructor assignment-operator rule-of-three
我不明白为什么我会这样做:
struct S {
int a;
S(int aa) : a(aa) {}
S() = default;
};
Run Code Online (Sandbox Code Playgroud)
为什么不说:
S() {} // instead of S() = default;
Run Code Online (Sandbox Code Playgroud)
为什么要为此引入一个新关键字?
std::swap()在排序甚至分配期间被许多std容器(例如std::list和std::vector)使用.
但是std实现swap()非常普遍,而且对于自定义类型来说效率很低.
因此,通过std::swap()使用自定义类型特定实现进行重载可以获得效率.但是如何实现它以便std容器使用它?
如果我覆盖operator=,复制构造函数会自动使用new运算符吗?同样,如果我定义了一个拷贝构造函数,会operator=自动"继承"拷贝构造函数的行为吗?
c++ constructor operators copy-constructor assignment-operator
PIMPL代表P ointer到IMPL ementation.实现代表"实现细节":类的用户不必关心的东西.
Qt自己的类实现通过使用PIMPL惯用法将接口与实现完全分开.然而,Qt提供的机制没有记录.怎么用?
我想这是关于Qt中"我如何进行PIMPL"的规范性问题.答案将由下面显示的简单坐标输入对话框界面激发.
当我们有任何半复杂的实现时,使用PIMPL的动机就变得明显了.这个问题给出了进一步的动机.即使是一个相当简单的类也必须在其界面中引入许多其他头文件.

基于PIMPL的接口非常干净且易读.
// CoordinateDialog.h
#include <QDialog>
#include <QVector3D>
class CoordinateDialogPrivate;
class CoordinateDialog : public QDialog
{
Q_OBJECT
Q_DECLARE_PRIVATE(CoordinateDialog)
#if QT_VERSION <= QT_VERSION_CHECK(5,0,0)
Q_PRIVATE_SLOT(d_func(), void onAccepted())
#endif
QScopedPointer<CoordinateDialogPrivate> const d_ptr;
public:
CoordinateDialog(QWidget * parent = 0, Qt::WindowFlags flags = 0);
~CoordinateDialog();
QVector3D coordinates() const;
Q_SIGNAL void acceptedCoordinates(const QVector3D &);
};
Q_DECLARE_METATYPE(QVector3D)
Run Code Online (Sandbox Code Playgroud)
基于Qt 5,C++ 11的接口不需要该Q_PRIVATE_SLOT行.
将其与非PIMPL接口进行比较,该接口将实现细节隐藏在接口的私有部分中.请注意必须包含多少其他代码.
// CoordinateDialog.h
#include <QDialog>
#include <QVector3D>
#include <QFormLayout>
#include <QDoubleSpinBox>
#include <QDialogButtonBox>
class CoordinateDialog : …Run Code Online (Sandbox Code Playgroud) 我正在阅读关于"五条规则"的这个很好的答案,我注意到一些我以前没有记得的事情:
class C {
...
C& operator=(const C&) & = default;
C& operator=(C&&) & = default;
...
};
Run Code Online (Sandbox Code Playgroud)
&放置在= default复制赋值运算符和移动赋值运算符前面的字符的用途是什么?有没有人有这方面的参考?
在底部更新
问题1:如何为管理相当繁重的资源的类实现五条规则,但是您希望它按值传递,因为这极大地简化并美化了它的用法?或者甚至不需要所有五项规则?
在实践中,我开始使用3D成像,其中图像通常是128*128*128双倍.能够写这样的东西会让数学变得更容易:
Data a = MakeData();
Data c = 5 * a + ( 1 + MakeMoreData() ) / 3;
Run Code Online (Sandbox Code Playgroud)
问题2:使用复制省略/ RVO /移动语义的组合,编译器应该能够以最少的复制完成此操作,不是吗?
我试图找出如何做到这一点,所以我从基础开始; 假设一个对象实现了实现复制和赋值的传统方式:
class AnObject
{
public:
AnObject( size_t n = 0 ) :
n( n ),
a( new int[ n ] )
{}
AnObject( const AnObject& rh ) :
n( rh.n ),
a( new int[ rh.n ] )
{
std::copy( rh.a, rh.a + n, a );
}
AnObject& operator = ( …Run Code Online (Sandbox Code Playgroud) 可能重复:
C++中的Nullable值
在C++中表示可空成员的最佳方法是什么?
在C#中,我们可以使用Nullable<T>类型.非常需要这样的数据类型,因为并非所有数据都具有有意义的价值.这是一个非常重要的数据类型,@ Jon Skeet花了整整一章,跨越了27页,仅Nullable<T>在他的优秀着作C#Depth中进行了描述.
一个简单的例子可以是一个Person类1,定义为:
struct Person
{
std::string Name;
DateTime Birth;
DateTime Death;
//...
};
Run Code Online (Sandbox Code Playgroud)
由于一个人总是有生日,所以Birth上述班级的成员总会有一些有意义的价值.但是怎么样Death?如果这个人还活着,它应该有什么价值呢?在C#中,此成员可以声明为Nullable<DataTime>2,null如果此人活着,则可以将其分配.
在C++中,解决这个问题的最佳方法是什么?截至目前,我只考虑了一个解决方案:将成员声明为指针:
DataTime *Death;
Run Code Online (Sandbox Code Playgroud)
现在它的价值可以是nullptr人活着的时候.但它强迫使用new死人,因为它会有一些有效的价值.它反过来意味着不能依赖编译器生成的默认复制语义代码.程序员必须编写复制构造函数,复制赋值,析构函数遵循三条规则(C++ 03),或者在C++ 11中规则,五条规则.
那么,除了制作指针之外,我们还有更好,更优雅的解决方案吗?
其他示例包括关系数据库表,因为在许多DBMS中,列可以为空.
这也有一个简写.人们可以写DataTime?这正是因为相同Nullable<DateTime>.
看作C++ 11支持移动语义,当从参数初始化数据成员时,我们是否应该尝试移动值而不是复制它?
这是一个示例,展示了如何在C++ 11之前解决这个问题:
struct foo {
std::vector<int> data;
explicit foo(const std::vector<int>& data)
: data(data)
{
}
};
Run Code Online (Sandbox Code Playgroud)
这里,将调用复制构造函数.
在C++ 11中,我们是否应该养成这样写的习惯:
struct foo {
std::vector<int> data;
explicit foo(std::vector<int> data)
: data(std::move(data))
{
}
};
Run Code Online (Sandbox Code Playgroud)
这里,移动构造函数将被调用...以及复制构造函数(如果传递的参数是左值),但好处是如果传递了右值,则将调用移动构造函数而不是复制构造函数.
我想知道是否有我遗漏的东西.
我在visual studio 11上尝试了一些新的C++ 11功能,从移动构造函数开始.我写了一个名为"MyClass"的简单类,其中包含一个移动构造函数:
class MyClass
{
public:
explicit MyClass( int aiCount )
: mpiSize( new int( aiCount ) ),
miSize2( aiCount)
{
}
MyClass( MyClass&& rcOther )
: mpiSize( rcOther.mpiSize )
, miSize( *rcOther.mpiSize )
{
rcOther.mpiSize = 0;
rcOther.miSize = 0;
}
~MyClass()
{
delete mpiSize;
}
private:
int *mpiSize;
int miSize2;
};
Run Code Online (Sandbox Code Playgroud)
我在这里有问题:
c++ ×10
c++11 ×6
c++-faq ×2
constructor ×1
nullable ×1
operators ×1
optimization ×1
performance ×1
pimpl-idiom ×1
qt ×1
stl ×1