假设我有一个类,其中复制构造函数是私有的而未实现(使对象不可复制)
class NonCopyable {
// whatever
private:
NonCopyable( const NonCopyable&);
void operator=(const NonCopyable&);
};
Run Code Online (Sandbox Code Playgroud)
现在在同一个类的一些成员函数中,我编写了返回该类对象的代码:
NonCopyable NonCopyable::Something()
{
return NonCopyable();
}
Run Code Online (Sandbox Code Playgroud)
这是RVO可以参与的情况.
RVO仍然要求可以访问复制构造函数.由于可以从同一个类成员函数中对复制构造函数进行可能的调用,因此可以访问复制构造函数.因此技术上RVO是可能的,尽管意图是禁止使用复制构造函数.
在这种情况下是否允许RVO?
如何为具有接口成员变量的类编写复制构造函数?
例如:
public class House{
// IAnimal is an interface
IAnimal pet;
public House(IAnimal pet){
this.pet = pet;
}
// my (non-working) attempt at a copy constructor
public House(House houseIn){
// The following line doesn't work because IAnimal (an interface) doesn't
// have a copy constructor
this.pet = new IAnimal(houseIn.pet);
}
}
Run Code Online (Sandbox Code Playgroud)
我被迫有一个混凝土Animal吗?如果是这样的话,似乎重复使用课程与狗的房子与猫的房子变得错综复杂!
你能给出一个简单或真实的例子来演示volatile复制构造函数的用法吗?
我只是想不出一个.
在更新一些代码以使用统一初始化时,我认为它将成为现在"旧式"括号样式的现代替代品.我知道情况并非总是如此(显而易见的例子vector<int>),但我偶然发现了另一个我不理解的差异.
class Object {
public:
Object() = default;
Object(const Object&) = default;
};
int main() {
Object o;
Object copy{o}; // error
Object copy2(o); // OK
}
Run Code Online (Sandbox Code Playgroud)
无法在clang3.5下编译并出现错误:(在gcc下也失败)
error: excess elements in struct initializer
Run Code Online (Sandbox Code Playgroud)
这有两个不同的变化Object使这项工作.向其添加数据成员,或为其提供空复制构造函数体
class Object {
private:
int i; // this fixes it
public:
Object() = default;
Object(const Object&) { } // and/or this fixes it as well
};
Run Code Online (Sandbox Code Playgroud)
我不明白为什么这些应该有所作为.
std::copy是一种更通用的方法,因为它可以处理具有不同值类型的容器(例如从中复制std::vector<float>到std::vector::<double>).但是当两个容器的值类型相同时,我是否使用复制构造函数而不是std::copy?
请考虑以下代码:
#include <iostream>
using namespace std;
class A
{
public:
int a;
A(): a(5)
{
cout << "Constructor\n";
}
A(const A &b)
{
a = b.a;
cout << "Copy Constructor\n";
}
A fun(A a)
{
return a;
}
};
int main()
{
A a, c;
A b = a.fun(c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面代码的输出g++ file.cpp是:
Constructor
Constructor
Copy Constructor
Copy Constructor
Run Code Online (Sandbox Code Playgroud)
上面代码的输出g++ -fno-elide-constructors file.cpp是:
Constructor
Constructor
Copy Constructor
Copy Constructor
Copy Constructor
Run Code Online (Sandbox Code Playgroud)
我知道返回值优化.我的问题是哪个复制构造函数的调用被删除(返回期间的临时对象或被复制到b的返回对象)?
如果省略的复制构造函数是用于创建b的构造函数,那么如何创建b(因为在这种情况下也没有构造函数调用)?
如果我替换行A b …
c++ copy-constructor temporary-objects return-value-optimization copy-elision
在C++ 11之前,我们可以通过编写类似于A a = 1;或多或少相当的东西来进行复制初始化A a = A(1);.也就是说,首先创建临时,然后调用复制ctor.无论版本是否复制,这必须是概念上的,并且必须可以访问复制文件.
使用C++ 11中的列表初始化,我们可以通过写入来进行复制列表初始化A a = {1, 2};.在我看来,这应该或多或少相当于A a = A(1, 2);.但是,在GCC和clang上,A a = {1, 2}即使复制和移动ctor不可访问(通过声明为私有)也会编译.但是,A a = 1;如果相应的复制/移动ctor不可访问,则不会在GCC或clang上编译.所以,A a = {1, 2};似乎或多或少等同于A a{1, 2};直接列表初始化.这与实际直接列表初始化之间的区别在于,A a = {1, 2};如果采用两个整数的ctor是显式的,则不会编译.在这方面,A a = {1, 2};类似于复制初始化.
所以,我的问题是:A a = {1, 2};概念上表达式的确切语义是什么?从概念上讲,复制省略不会妨碍.
c++ copy-constructor copy-initialization c++11 list-initialization
我的问题涉及如何返回没有复制构造函数的对象.举一个例子,让我们想象一下,我有一些bigResource位于堆中,让我们说我用它来跟踪它unique_ptr.现在假设我将此资源的所有权交给了毛毛虫.然后我有一个CaterpillarWithBigResource.现在在某些时候,这CaterpillarWithBigResource将变成一个ButterflyWithBigResource,所以Caterpillar对象必须将所有权转移到Butterfly对象.
我编写了以下代码来模拟情况:
#include <cstdlib>
#include <iostream>
#include <memory>
class ButterflyWithBigResource {
public:
// If I uncomment just this line, I get an error
// ButterflyWithBigResource(const ButterflyWithBigResource& other) = default;
// If I uncomment just this line, I get an error
// ButterflyWithBigResource(const ButterflyWithBigResource& other) = delete;
// With both above lines commented out, I get no errors, and the program runs fine.
ButterflyWithBigResource(std::unique_ptr<int>&& bigResource) :
bigResource(std::move(bigResource)) …Run Code Online (Sandbox Code Playgroud) 假设我有一个包含多个构造函数的类,其中一个是复制构造函数(复制对象):
public class Rectangle {
int width, height;
public Rectangle(int width, int height) {
this.width = width;
this.height = height;
}
public Rectangle(Rectangle source) {
this(source.width, source.height);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有什么办法可以让检查,如果source是null在拷贝构造函数和抛出IllegalArgumentException,如果它是什么?因为其他构造函数调用必须是我的构造函数中的第一个语句.
任何人都可以解释*p=*q这个C++代码的含义吗?这是一个复制构造函数的概念吗?
class A{
//any code
}
int main(){
A *p=new A();
A *q=new A();
*p=*q;
return 0;
}
Run Code Online (Sandbox Code Playgroud) copy-constructor ×10
c++ ×8
c++11 ×3
java ×2
constructor ×1
containers ×1
copy-elision ×1
interface ×1
pointers ×1
rvo ×1
stl ×1