第一个例子:
#include <iostream>
#include <memory>
using namespace std;
struct A {
unique_ptr<int> ref;
A(const A&) = delete;
A(A&&) = default;
A(const int i) : ref(new int(i)) { }
~A() = default;
};
int main()
{
A a[2] = { 0, 1 };
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它完美地运作.所以这里使用了MOVE构造函数.
让我们删除移动构造函数并添加一个副本:
#include <iostream>
#include <memory>
using namespace std;
struct A {
unique_ptr<int> ref;
A(const A&a)
: ref( a.ref.get() ? new int(*a.ref) : nullptr )
{ }
A(A&&) = delete;
A(const int i) : ref(new …Run Code Online (Sandbox Code Playgroud) 考虑以下程序:
#include <iostream>
struct Test
{
int a;
Test() : a(3)
{ }
Test(const Test& t...)
{
std::cout<<"Copy constructor called\n";
a=t.a;
}
int get_a()
{
return a;
}
~Test()
{
std::cout<<"Destructor is called\n";
}
};
int main()
{
Test t;
Test* t1=new Test(t);
std::cout<<t.get_a()<<'\n';
std::cout<<t1->get_a()<<'\n';
delete t1;
}
Run Code Online (Sandbox Code Playgroud)
仔细观察复制构造函数参数中的三个点我尝试这个程序时真的很惊讶.有什么用?这是什么意思?
语言规范对此有何看法?
我知道三个点用于表示变量函数(如等)中的变长参数printf()以及scanf()C99引入的可变参数宏.在C++中,如果我没有错,它们将用于可变参数模板.
这段代码是否形成良好?这个可变参数构造函数是否可以使用任意数量的参数?
它在g ++ 4.8.1和MSVS 2010上编译并运行良好.
据我所知,复制构造函数必须是T(const T&)或者T(T&).如果我想在签名中添加默认参数怎么办?
T(const T&, double f = 1.0);
Run Code Online (Sandbox Code Playgroud)
这会符合标准吗?
是否允许编译器删除按值捕获所需的副本?
vector<Image> movie1;
apply( [=movie1](){ return movie1.size(); } );
Run Code Online (Sandbox Code Playgroud)
movie1?
apply实际上并没有改变 movie1?const仿函数吗?vector有一个移动构造函数和移动分配?
Image,以防止昂贵的副本?void operate(vector<Image> movie)我需要能够复制Qwidget,因此我可以复制一个窗口,因为它会在运行时更改.这可能吗?
void Duplicate(QWidget * Show)
{
//I tried...
Qwidget Shw = *Show; //but operator= is private
//and the copy constructor (I think), which is also private
Qwidget Shw(*Show);
//
Shw.Show();
}
Run Code Online (Sandbox Code Playgroud) 在VS 2010 SP1中,以下内容:
class Foo
{
public:
Foo() { }
Foo(Foo const&) = delete; // Line 365
Foo& operator=(Foo const&) = delete; // Line 366
};
Run Code Online (Sandbox Code Playgroud)
不编译.它抱怨说:
CPPConsole.cpp(365):错误C2059:语法错误:';'
CPPConsole.cpp(365):错误C2238:';'之前的意外标记
CPPConsole.cpp(366):错误C2059:语法错误:';'
CPPConsole.cpp(366):错误C2238:';'之前的意外令牌
这不支持吗?奇怪的是,Intellisense似乎认识到这种结构.它说"IntelliSense:function"Foo :: operator =(const Foo&)"(在第366行声明)无法引用 - 它是一个已删除的函数"
我错过了什么?
请看下面的例子:
class Base
{
protected:
int m_nValue;
public:
Base(int nValue)
: m_nValue(nValue)
{
}
const char* GetName() { return "Base"; }
int GetValue() { return m_nValue; }
};
class Derived: public Base
{
public:
Derived(int nValue)
: Base(nValue)
{
}
Derived( const Base &d ){
std::cout << "copy constructor\n";
}
const char* GetName() { return "Derived"; }
int GetValueDoubled() { return m_nValue * 2; }
};
Run Code Online (Sandbox Code Playgroud)
这段代码不断给我一个错误,即基类没有默认的构造函数.当我宣布一切都好的时候.但是当我不这样做时,代码不起作用.
如何在派生类中声明复制构造函数而不在基类中声明默认的构造函数?
Thnaks.
在阅读了@Mehrdad 最近的问题之后,哪些类应该是不可移动的,因此是不可复制的,我开始想知道是否存在可以复制但不能移动的类的用例.从技术上讲,这是可能的:
struct S
{
S() { }
S(S const& s) { }
S(S&&) = delete;
};
S foo()
{
S s1;
S s2(s1); // OK (copyable)
return s1; // ERROR! (non-movable)
}
Run Code Online (Sandbox Code Playgroud)
虽然S有一个复制构造函数,但它显然不会对CopyConstructible概念进行建模,因为这反过来又是MoveConstructible概念的改进,需要存在(未删除的)移动构造函数(参见§17.6.3.1/2,表21) .
是否有类似S上述类型的用例,可复制但不可 CopyConstructible 移动?如果没有,为什么不禁止在同一个类中声明复制构造函数和已删除的移动构造函数?
std::unique_ptr有一个已删除的复制构造函数,这意味着如果您unique_ptr的类中有一个Foo作为数据成员,那么您必须编写自己的复制构造函数Foo并手动深层复制该成员(即使编译器生成的复制构造函数对所有人都可以.其他成员).
为了能够以多态方式进行复制,clone()可以使用方法模式.让我们假设我们的对象有一个像这样的克隆方法:
class Base {
virtual std::unique_ptr<Base> clone() = 0;
};
Run Code Online (Sandbox Code Playgroud)
Foo现在看起来像这样:
class Foo {
public:
...
Foo(Foo const& other)
: b(other.b->clone())
, // init 10 more members that could otherwise be auto-copied just fine
// with the automatically generated copy constructor
{}
...
private:
std::unique_ptr<Base> b;
//10 more data members
};
Run Code Online (Sandbox Code Playgroud)
现在,我找到了一种自动克隆的方法Foo::b,通过编写一个包装器unique_ptr来定义复制构造函数和通过调用赋值clone.
template <typename T>
class auto_cloned_unique_ptr
{
private:
std::unique_ptr<T> up;
public:
// copy …Run Code Online (Sandbox Code Playgroud) 我有一个用例,我的对象不得以任何方式复制.我在下面写了一个夸张的复制构造函数和复制赋值运算符删除的完整列表.有这么多,我无法确定使用哪些,有时这让我变得偏执.我不必在我的代码中全部写出来,是吗?因此,为了防止任何类型的对象复制,我应该使用哪些对象?
MyClass ( MyClass &) = delete;
MyClass (const MyClass &) = delete;
MyClass ( MyClass &&) = delete;
MyClass (const MyClass &&) = delete;
MyClass operator=( MyClass &) = delete;
MyClass operator=(const MyClass &) = delete;
const MyClass operator=( MyClass &) = delete;
const MyClass operator=(const MyClass &) = delete;
MyClass & operator=( MyClass &) = delete;
MyClass & operator=(const MyClass &) = delete;
const MyClass & operator=( MyClass &) = delete;
const MyClass & operator=(const MyClass &) = …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor copy-assignment deleted-functions implicit-methods
copy-constructor ×10
c++ ×9
c++11 ×5
clone ×1
inheritance ×1
lambda ×1
qt ×1
qwidget ×1
unique-ptr ×1