相关疑难解决方法(0)

我们何时必须使用复制构造函数?

我知道C++编译器为类创建了一个复制构造函数.在这种情况下,我们必须编写用户定义的复制构造函数吗?你能举一些例子吗?

c++ copy-constructor

80
推荐指数
4
解决办法
7万
查看次数

你最喜欢的C++ Coding Style成语是什么?

你最喜欢的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++ coding-style

60
推荐指数
14
解决办法
2万
查看次数

动态分配对象数组

这是一个初学者的问题,但我很长一段时间没有做过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,这意味着myArrayA实例的内部delete []变为-ed.

所以我认为我的语法必定是非常错误的?我想有一些看起来像矫枉过正的修复,我希望避免:

  • 为...创建复制构造函数A …

c++ pointers destructor memory-management copy-constructor

56
推荐指数
3
解决办法
13万
查看次数

如何使用Qt的PIMPL习语?

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)

c++ qt pimpl-idiom

50
推荐指数
1
解决办法
1万
查看次数

为什么std :: swap有这么多特化?

在查看文档时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)

我也想知道我是否应该为自定义类编写自己的专业,
或者只是依赖于模板版本.

c++ templates swap stl template-specialization

41
推荐指数
5
解决办法
3828
查看次数

C++ Wrapper类的含义是什么?

我在理解包装类时有点麻烦.如果有人可以帮助提供适当的例子,那将是很好的.

  1. 什么是C++包装类以及编写它的具体情况是什么?
  2. 有什么用途?

谢谢.

c++ class wrapper

38
推荐指数
3
解决办法
7万
查看次数

具有参考成员的分配操作员

这是创建具有引用成员的赋值运算符的有效方法吗?

#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 ++倾向于表现出最不期望的未定义行为时,以及所有说它不可能的人,我认为我错过了一些问题.我错过了什么吗?

c++ reference

32
推荐指数
2
解决办法
1万
查看次数

赋值运算符在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)

它完美地工作并且避免了复制构造函数问题,但是对于这个问题(对我来说)是否存在任何未知问题?

c++ operator-overloading

32
推荐指数
3
解决办法
10万
查看次数

什么是复制省略以及它如何优化复制和交换习惯用法?

我正在阅读复制和交换.

我尝试阅读Copy Elision上的一些链接,但无法弄清楚它的含义.有人可以解释一下这种优化是什么,特别是下面的文字是什么意思

这不仅仅是为了方便,而且实际上是一种优化.如果参数绑定到左值(另一个非常量对象),则在创建参数时会自动创建对象的副本.但是,当s绑定到rvalue(临时对象,文字)时,通常会省略该副本,从而保存对复制构造函数和析构函数的调用.在赋值运算符的早期版本中,参数被接受为const引用,当引用绑定到右值时,不会发生复制省略.这导致创建和销毁另外的对象.

c++ optimization copy-and-swap copy-elision

30
推荐指数
1
解决办法
8465
查看次数

为什么不能使用非成员函数来重载赋值运算符?

赋值运算符可以使用成员函数重载,但不能使用非成员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++ operator-overloading assignment-operator

30
推荐指数
4
解决办法
2万
查看次数