我正在浏览Copy Constructors,我已经浏览了堆栈中的链接和其他链接.但我不清楚以下几点.
我的意思是我们需要使用Copy Constructor的确切情况或场景是什么.有人可以用一个例子解释或指出链接,这样我就可以明确地理解它们.
以下是我为了解什么是复制构造函数而经历的链接.
http://www.programmerinterview.com/index.php/java-questions/how-copy-constructors-work/
https://deepeshdarshan.wordpress.com/2013/12/05/copy-constructors-in-java/
第二个链接解释了"为什么"和"在哪里"使用复制构造函数.但我仍然不清楚它.
下面是我的Employee.java类
package com.test;
/**
* @author avinashd
*
*/
public class Employee {
private String rollNo;
private String name;
//constructor
public Employee(String rollNo, String name){
this.rollNo = rollNo;
this.name = name;
}
//copy constructor
public Employee(Employee employee){
this.rollNo = employee.rollNo;
this.name = employee.name;
}
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void …
Run Code Online (Sandbox Code Playgroud) 考虑以下程序:
#include <vector>
#include <iostream>
class A {
int x;
public:
A(int n) noexcept : x(n) { std::cout << "ctor with value\n"; }
A(const A& other) noexcept : x(other.x) { std::cout << "copy ctor\n"; }
A(A&& other) noexcept : x(other.x) { std::cout << "move ctor\n"; }
~A() { std::cout << "dtor\n"; } // (*)
};
int main()
{
std::vector<A> v;
v.emplace_back(123);
v.emplace_back(456);
}
Run Code Online (Sandbox Code Playgroud)
如果我运行该程序,我会得到(GodBolt):
ctor with value
ctor with value
move ctor
dtor
dtor
dtor
Run Code Online (Sandbox Code Playgroud)
……这符合我的预期。但是,如果在线(*)
我将析构函数标记为可能抛出,那么我会 …
可以为已经有用户定义的构造函数但不是复制构造函数的类调用(隐式)默认 复制构造函数吗?
如果可能的话,假设我们明确定义了类的复制构造函数,现在可以调用(隐式)默认构造函数吗?
我有一个模板'Foo',它拥有一个T,我希望它有一个可变参数构造函数,将它的参数转发给T的构造函数:
template<typename T>
struct Foo {
Foo()
: t() {}
Foo(const Foo& other)
: t(other.t) {}
template<typename ...Args>
Foo(Args&&... args)
: t(std::forward<Args>(args)...) {}
T t;
};
Run Code Online (Sandbox Code Playgroud)
但是,这会导致Foo无法复制:
int main(int argc, char* argv[]) {
Foo<std::shared_ptr<int>> x(new int(42));
decltype(x) copy_of_x(x); // FAILS TO COMPILE
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
因为,根据这个答案,参数的非常量导致可变参数构造函数更好地匹配.出于显而易见的原因,我不想强制我的调用者使用const_cast.
我找到的一个可能的解决方案是为Foo编写一个"复制构造函数",它采用非const Foo并使用构造函数转发:
Foo(Foo& other)
: Foo(const_cast<const Foo&>(other)) {}
Run Code Online (Sandbox Code Playgroud)
当定义了这个构造函数时,事情再次起作用:现在首选非const Foo参数copy ctor.然而,这对我来说似乎非常粗略,因为这种"治愈"似乎比疾病更糟糕.
是否有另一种方法来实现这种效果,表明自然拷贝构造函数应该优先于可变参数构造函数?如果没有,定义这个非const参数复制构造函数会有什么不利后果吗?
#include <iostream>
struct uct
{
uct() { std::cerr << "default" << std::endl; }
uct(const uct &) { std::cerr << "copy" << std::endl; }
uct( uct&&) { std::cerr << "move" << std::endl; }
uct(const int &) { std::cerr << "int" << std::endl; }
uct( int &&) { std::cerr << "int" << std::endl; }
template <typename T>
uct(T &&) { std::cerr << "template" << std::endl; }
};
int main()
{
uct u1 ; // default
uct u2( 5); // int
uct u3(u1); …
Run Code Online (Sandbox Code Playgroud) c++ copy-constructor constructor-overloading function-templates overload-resolution
这是复制构造函数[class.copy.ctor / 1]的定义:
如果类X的非模板构造函数的第一个参数为X&,const X&,volatile X&或const volatile X&类型,并且没有其他参数,或者所有其他参数都具有默认参数([dcl。 fct.default])。
为什么标准将模板排除为复制构造函数?
在这个简单的示例中,两个构造函数都是副本构造函数:
struct Foo {
Foo(const Foo &); // copy constructor
Foo(Foo &); // copy constructor
};
Run Code Online (Sandbox Code Playgroud)
参见以下类似示例:
struct Foo {
Foo() = default;
template <typename T>
Foo(T &) {
printf("here\n");
}
};
int main() {
Foo a;
Foo b = a;
}
Run Code Online (Sandbox Code Playgroud)
在此示例中,here
将被打印。因此,似乎我的模板构造函数是一个复制构造函数,至少它的行为类似于一个(在通常调用复制构造函数的上下文中被调用)。
为什么文本中存在“非模板”要求?
这是我长期以来一直想知道的事情.请看以下示例:
struct matrix
{
float data[16];
};
Run Code Online (Sandbox Code Playgroud)
我知道默认构造函数和析构函数在这个特定示例中做了什么(没有),但是复制构造函数和复制赋值运算符呢?
struct matrix
{
float data[16];
// automatically generated copy constructor
matrix(const matrix& that) : // What happens here?
{
// (or here?)
}
// automatically generated copy assignment operator
matrix& operator=(const matrix& that)
{
// What happens here?
return *this;
}
};
Run Code Online (Sandbox Code Playgroud)
它涉及std::copy
或std::uninitialized_copy
或memcpy
或memmove
或什么?
复制其中一些成员未初始化的结构是否有效?
我怀疑这是未定义的行为,但如果是这样,则将任何未初始化的成员留在结构中(即使这些成员从未直接使用)非常危险。所以我想知道标准中是否有某些内容允许这样做。
例如,这有效吗?
struct Data {
int a, b;
};
int main() {
Data data;
data.a = 5;
Data data2 = data;
}
Run Code Online (Sandbox Code Playgroud) 我知道c ++中的以下情况,其中将调用复制构造函数:
当为现有对象分配其自己的类的对象时
MyClass A,B;
A = new MyClass();
B=A; //copy constructor called
Run Code Online (Sandbox Code Playgroud)如果函数接收作为参数,按值传递,则为类的对象
void foo(MyClass a);
foo(a); //copy constructor invoked
Run Code Online (Sandbox Code Playgroud)当函数返回(按值)类的对象时
MyClass foo ()
{
MyClass temp;
....
return temp; //copy constructor called
}
Run Code Online (Sandbox Code Playgroud)请随时纠正我所犯的任何错误; 但是如果有任何其他情况需要调用复制构造函数,我会更好奇.
在Visual Studio 2013(版本12.0.31101.00 Update 4)中编译此代码段时没有错误
class A
{
public:
A(){}
A(A &&){}
};
int main(int, char*)
{
A a;
new A(a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
虽然它在Visual Studio 2015 RC(版本14.0.22823.1 D14REL)中使用此错误进行编译:
1>------ Build started: Project: foo, Configuration: Debug Win32 ------
1> foo.cpp
1>c:\dev\foo\foo.cpp(11): error C2280: 'A::A(const A &)': attempting to reference a deleted function
1> c:\dev\foo\foo.cpp(6): note: compiler has generated 'A::A' here
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Run Code Online (Sandbox Code Playgroud)
我认为Visual Studio 2015附带的编译器生成了复制构造函数并将其标记为=delete
,因此我得到了错误C2280(顺便说一句,我在msdn.microsoft.com上找不到文档).
现在,假设我有一个可与Visual Studio 2013兼容的代码库(它可以工作,因为它依赖于编译器自动生成的代码)但由于C2280而无法与Visual Studio …
copy-constructor ×10
c++ ×9
constructor ×3
visual-c++ ×2
arrays ×1
c++11 ×1
c++14 ×1
copy ×1
default ×1
java ×1
stdvector ×1
templates ×1