我知道C++编译器为类创建了一个复制构造函数.在这种情况下,我们必须编写用户定义的复制构造函数吗?你能举一些例子吗?
你最喜欢的C++编码风格是什么?我问的是样式或编码排版,例如你在哪里放大括号,在关键字后面有空格,缩进的大小等等.这与最佳实践或要求相反,例如总是删除数组delete[].
以下是我最喜欢的一个示例:在C++类初始值设定项中,我们将分隔符放在行的前面而不是后面.这样可以更容易地保持最新状态.这也意味着版本之间的源代码控制差异更清晰.
TextFileProcessor::
TextFileProcessor( class ConstStringFinder& theConstStringFinder )
: TextFileProcessor_Base( theConstStringFinder )
, m_ThreadHandle ( NULL )
, m_startNLSearch ( 0 )
, m_endNLSearch ( 0 )
, m_LineEndGetIdx ( 0 )
, m_LineEndPutIdx ( 0 )
, m_LineEnds ( new const void*[ sc_LineEndSize ] )
{
;
}
Run Code Online (Sandbox Code Playgroud) 这是一个初学者的问题,但我很长一段时间没有做过C++,所以这里......
我有一个包含动态分配数组的类,比方说
class A
{
int* myArray;
A()
{
myArray = 0;
}
A(int size)
{
myArray = new int[size];
}
~A()
{
// Note that as per MikeB's helpful style critique, no need to check against 0.
delete [] myArray;
}
}
Run Code Online (Sandbox Code Playgroud)
但现在我想创建一个动态分配的这些类的数组.这是我目前的代码:
A* arrayOfAs = new A[5];
for (int i = 0; i < 5; ++i)
{
arrayOfAs[i] = A(3);
}
Run Code Online (Sandbox Code Playgroud)
但这种情况非常糟糕.因为在循环迭代完成时,A(通过A(3)调用)创建的新对象会被破坏for,这意味着myArray该A实例的内部delete []变为-ed.
所以我认为我的语法必定是非常错误的?我想有一些看起来像矫枉过正的修复,我希望避免:
A …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) 在查看文档时std::swap,我看到了很多专业化.
看起来每个STL容器以及许多其他std工具都有专门的交换.
我想借助模板,我们不需要所有这些专业化?
例如,
如果我自己编写,pair它可以与模板化版本一起正常工作:
template<class T1,class T2>
struct my_pair{
T1 t1;
T2 t2;
};
int main() {
my_pair<int,char> x{1,'a'};
my_pair<int,char> y{2,'b'};
std::swap(x,y);
}
Run Code Online (Sandbox Code Playgroud)
那么从专业化中获得了什么std::pair?
template< class T1, class T2 >
void swap( pair<T1,T2>& lhs, pair<T1,T2>& rhs );
Run Code Online (Sandbox Code Playgroud)
我也想知道我是否应该为自定义类编写自己的专业,
或者只是依赖于模板版本.
我在理解包装类时有点麻烦.如果有人可以帮助提供适当的例子,那将是很好的.
谢谢.
这是创建具有引用成员的赋值运算符的有效方法吗?
#include <new>
struct A
{
int &ref;
A(int &Ref) : ref(Ref) { }
A(const A &second) : ref(second.ref) { }
A &operator =(const A &second)
{
if(this == &second)
return *this;
this->~A();
new(this) A(second);
return *this;
}
}
Run Code Online (Sandbox Code Playgroud)
它似乎编译并运行良好,但是当c ++倾向于表现出最不期望的未定义行为时,以及所有说它不可能的人,我认为我错过了一些问题.我错过了什么吗?
我使用以下代码进行赋值运算符重载:
SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs)
{
if(this == &rhs)
return *this;
itsRadius = rhs.getRadius();
return *this;
}
Run Code Online (Sandbox Code Playgroud)
我的复制构造函数是这样的:
SimpleCircle::SimpleCircle(const SimpleCircle & rhs)
{
itsRadius = rhs.getRadius();
}
Run Code Online (Sandbox Code Playgroud)
在上面的运算符重载代码中,复制构造函数被调用,因为正在创建一个新对象; 因此我使用了以下代码:
SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
if(this == &rhs)
return *this;
itsRadius = rhs.getRadius();
return *this;
}
Run Code Online (Sandbox Code Playgroud)
它完美地工作并且避免了复制构造函数问题,但是对于这个问题(对我来说)是否存在任何未知问题?
我正在阅读复制和交换.
我尝试阅读Copy Elision上的一些链接,但无法弄清楚它的含义.有人可以解释一下这种优化是什么,特别是下面的文字是什么意思
这不仅仅是为了方便,而且实际上是一种优化.如果参数绑定到左值(另一个非常量对象),则在创建参数时会自动创建对象的副本.但是,当s绑定到rvalue(临时对象,文字)时,通常会省略该副本,从而保存对复制构造函数和析构函数的调用.在赋值运算符的早期版本中,参数被接受为const引用,当引用绑定到右值时,不会发生复制省略.这导致创建和销毁另外的对象.
赋值运算符可以使用成员函数重载,但不能使用非成员friend函数重载:
class Test
{
int a;
public:
Test(int x)
:a(x)
{}
friend Test& operator=(Test &obj1, Test &obj2);
};
Test& operator=(Test &obj1, Test &obj2)//Not implemented fully. just for test.
{
return obj1;
}
Run Code Online (Sandbox Code Playgroud)
它会导致此错误:
错误C2801:'operator ='必须是非静态成员
为什么friend函数不能用于重载赋值运算符?编译器允许重载其他运算符,例如+=和-=使用friend.支持的固有问题/限制是operator=什么?
c++ ×10
class ×1
coding-style ×1
copy-elision ×1
destructor ×1
optimization ×1
pimpl-idiom ×1
pointers ×1
qt ×1
reference ×1
stl ×1
swap ×1
templates ×1
wrapper ×1