以下代码在Visual C++ 2013中编译良好,但不在GCC或Clang下编译.
哪个是对的?
通过隐式转换返回对象时是否需要可访问的复制构造函数?
class Noncopyable
{
Noncopyable(Noncopyable const &);
public:
Noncopyable(int = 0) { }
};
Noncopyable foo() { return 0; }
int main()
{
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC:
error: 'Noncopyable::Noncopyable(const Noncopyable&)' is private
Noncopyable(Noncopyable const &);
^
error: within this context
Noncopyable foo() { return 0; }
Run Code Online (Sandbox Code Playgroud)
铛:
error: calling a private constructor of class 'Noncopyable'
Noncopyable foo() { return 0; }
^
note: implicitly declared private here
Noncopyable(Noncopyable const &);
^
warning: C++98 requires an …Run Code Online (Sandbox Code Playgroud) 使用构造函数或实例函数复制对象实例的优缺点是什么?
例A:
type
TMyObject = class
strict private
FField: integer;
public
constructor Create(srcObj: TMyObject); overload;
//alternatively:
//constructor CreateFrom(srcObj: TMyObject);
property Field: integer read FField;
end;
constructor TMyObject.Create(srcObj: TMyObject);
begin
inherited Create;
FField := srcObj.Field;
end;
Run Code Online (Sandbox Code Playgroud)
例B:
type
TMyObject = class
strict private
FField: integer;
public
function Clone: TMyObject;
property Field: integer read FField;
end;
function TMyObject.Clone: TMyObject;
begin
Result := TMyObject.Create;
Result.FField := FField;
end;
Run Code Online (Sandbox Code Playgroud)
一个主要的区别立即浮出水面 - 在后一种情况下,Create构造函数必须是虚拟的,以便可以基于TMyObject构建支持Clone的类层次结构.
假设这不是问题 - TMyObject和基于它的所有内容完全在我的控制之下.在Delphi中进行复制构造函数的首选方法是什么?您觉得哪个版本更具可读性?你什么时候使用前者或后者?讨论.:)
编辑:我对第一个例子的主要关注是,与第二种方法相比,使用率非常高,即
newObj := TMyObject.Create(oldObj)
Run Code Online (Sandbox Code Playgroud)
与
newObj := oldObj.Clone;
Run Code Online (Sandbox Code Playgroud)
EDIT2或"我为什么要单行操作" …
有时需要禁止C++类中的复制构造函数,以使类变为"不可复制".当然,operator=应该同时禁止.
到目前为止,我已经看到了两种方法.方法1是将方法声明为private并且不给它实现:
class Class {
//useful stuff, then
private:
Class( const Class& ); //not implemented anywhere
void operator=( const Class& ); //not implemented anywhere
};
Run Code Online (Sandbox Code Playgroud)
方法2是将方法声明为private并将其赋予"空"实现:
class Class {
//useful stuff, then
private:
Class( const Class& ) {}
void operator=( const Class& ) {}
};
Run Code Online (Sandbox Code Playgroud)
IMO第一个更好 - 即使有一些意外的原因导致从同一个类成员函数调用复制构造函数,稍后会出现链接器错误.在第二种情况下,在运行时之前不会注意到这种情况.
第一种方法有任何严重的缺点吗?什么是更好的方式,如果有的,为什么?
我四处搜索,似乎为了执行此操作,我需要更改我的Base类,并想知道这是否是最好的方法.例如,我有一个Base类:
class Base {}
Run Code Online (Sandbox Code Playgroud)
然后是一长串派生类:
class Derived_1:: public Base {}
class Derived_2:: public Derived_1{}
...
...
class Derived_n:: public Derived_M{}
Run Code Online (Sandbox Code Playgroud)
然后我又上了一堂课:
class DeepCopy
{
Base * basePtr;
public:
DeepCopy(DeepCopy & dc) {}
}
Run Code Online (Sandbox Code Playgroud)
假设Base类和Derived_x类复制构造函数已正确编码,那么为DeepCopy编写复制构造函数的最佳方法是什么.我们如何知道我们要复制的对象的basePtr中的类?
我能想到的唯一方法就是使用RTTI,但是使用一长串的dynamic_cast似乎不对.此外,它需要DeepCopy来了解Base类的继承层次结构.
我看到的另一种方法是在这里.但它需要Base和Derived类实现克隆方法.
那么有一个更简单,标准的方法吗?
最近我正在重读ISO C++标准,并发现了非常有趣的说明:
请注意,
std::vector上式的唯一约束T的std::vector<T>是该类型T必须有拷贝构造函数.实际上,如果在插入时向量的内存已满,则分配一个新的内存size = 2 * oldSize(这是依赖于实现的),然后在其中复制旧元素并插入该元素.
可是等等??
要分配类型的新内存,我们需要这样的东西, ptr = new T[2*size];
T可能没有默认构造函数?std::vector用"仅复制构造器"来做到这一点?使用了哪些实现和语言习语?请考虑以下代码:
#include <iostream>
#include <vector>
using namespace std;
class A
{
public:
A(int) { cout << "int" << endl; }
A(A&&) { cout << "move" << endl; }
A(const A&) { cout << "copy" << endl; }
};
int main()
{
vector<A> v
{
A(10), A(20), A(30)
};
_getch();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是:
int
int
int
copy
copy
copy
Run Code Online (Sandbox Code Playgroud)
A(10),A(20)并且A(30)是临时对象,对不对?
那么为什么复制构造函数被调用?不应该调用移动构造函数吗?
路过move(A(10)),move(A(20)),move(A(30))相反,输出为:
int
move
int
move
int
move
copy …Run Code Online (Sandbox Code Playgroud) 这是功课
我正在为我的C++类实现一个链表类,而复制构造函数对我来说非常困惑.
链表由称为Elems的结构组成:
struct Elem
{
int pri;
data info;
Elem * next;
};
Elem * head;
Run Code Online (Sandbox Code Playgroud)
info是一个单独的自定义类,存储在Elem中.
复制构造函数的签名是:
linkedList::linkedList( const linkedList &v )
Run Code Online (Sandbox Code Playgroud)
我遇到的问题主要是采用我的逻辑并实际将其编写为代码.
我的总体想法是:
这是一般的想法吗?
任何帮助都会很棒.记住,这是作业,所以请不要直接回答!
感谢您的时间
================================================== ================================================== ================================================== ==============
感谢大家的时间!
我想我已经弄清楚了:
//Copy Constructor
LinkedList::LinkedList( const LinkedList &v )
{
Elem * p1 = 0;//current
Elem * p2 = 0;//next
if( v.head == 0 )
head = 0;
else
{
head = new Elem;
head …Run Code Online (Sandbox Code Playgroud) 我有以下代码来测试我对C++中基本指针的理解:
// Integer.cpp
#include "Integer.h"
Integer::Integer()
{
value = new int;
*value = 0;
}
Integer::Integer( int intVal )
{
value = new int;
*value = intVal;
}
Integer::~Integer()
{
delete value;
}
Integer::Integer(const Integer &rhInt)
{
value = new int;
*value = *rhInt.value;
}
int Integer::getInteger() const
{
return *value;
}
void Integer::setInteger( int newInteger )
{
*value = newInteger;
}
Integer& Integer::operator=( const Integer& rhInt )
{
*value = *rhInt.value;
return *this;
}
// IntegerTest.cpp
#include <iostream>
#include …Run Code Online (Sandbox Code Playgroud) 这可能是一个明显答案或重复的问题.如果有,抱歉,我会删除它.
为什么不复制构造函数(如默认ctors或dtors),以便在调用派生类的复制构造函数之前调用基类的复制构造函数?对于复制构造函数和析构函数,它们分别在从base-to-derived和derived-to-base的链中被调用.为什么复制构造函数不是这种情况?例如,这段代码:
class Base {
public:
Base() : basedata(rand()) { }
Base(const Base& src) : basedata(src.basedata) {
cout << "Base::Base(const Base&)" << endl;
}
void printdata() {
cout << basedata << endl;
}
private:
int basedata;
};
class Derived : public Base {
public:
Derived() { }
Derived(const Derived& d) {
cout << "Derived::Derived(const Derived&)" << endl;
}
};
srand(time(0));
Derived d1; // basedata is initialised to rand() thanks to Base::Base()
d1.printdata(); // prints the random number
Derived d2 = …Run Code Online (Sandbox Code Playgroud) 我对以下代码有点困惑:
struct A {
std::atomic<int> a = 0;
};
Run Code Online (Sandbox Code Playgroud)
这给出了一个错误:
复制"std :: atomic"类型的成员子对象调用已删除的构造函数
但几乎相同的代码确实有效:
struct A {
std::atomic<int> a = {0};
};
Run Code Online (Sandbox Code Playgroud)
Okey,如果第一个变体需要复制构造函数,那么它必须使用operator=().可是等等!这个运算符完美地工作,没有复制构造函数:
A a;
a.a = 1;
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释如何在简单操作方面扩展两个就地初始化吗?为什么第一个需要复制构造函数?
copy-constructor ×10
c++ ×9
constructor ×3
c++11 ×2
atomic ×1
class-design ×1
copy-elision ×1
deep-copy ×1
delphi ×1
inheritance ×1
linked-list ×1
pointers ×1
stl ×1
vector ×1