使用"big 3"(构造函数,复制构造函数,析构函数)进行简单的类:
#include <vector>
using namespace std; //actually goes in the C file that links to this header file
...
class planets(){ //stores mass and radii data for planets in a solar system.
public:
vector <double> mass;
vector <double> radius;
//constructor
planets( int numObj ){
for(int i=0; i<numObj; i++){
mass.push_back(8.0); //some default values.
radius.push_back(2.0);
}
}
//copy constructor
planets(const planets &p){
vector <double> mass(p.mass); //copy vectors into new class.
vector <double> radius(p.radius);
}
//destructor
~planets(){
delete mass; //ERROR: (...) argument …Run Code Online (Sandbox Code Playgroud) 在C++ Primer一书中,它有一个C风格字符数组的代码,并展示了如何=在第15.3条Operator =中重载运算符.
String& String::operator=( const char *sobj )
{
// sobj is the null pointer,
if ( ! sobj ) {
_size = 0;
delete[] _string;
_string = 0;
}
else {
_size = strlen( sobj );
delete[] _string;
_string = new char[ _size + 1 ];
strcpy( _string, sobj );
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
现在我想知道为什么String &在下面的代码执行相同的工作时需要返回引用,没有任何问题:
void String::operator=( const char *sobj )
{
// sobj is the null …Run Code Online (Sandbox Code Playgroud) 我需要编写一个复制构造函数,深度复制一个内容std::shared_ptr.但是,int a, b, c, d, e;在类中还定义了一堆变量.有没有办法在我的新重载的代码中生成默认的复制构造函数代码(或调用默认的复制构造函数).
这是一个带有注释的代码片段,希望能够澄清问题.
class Foo {
public:
Foo() {}
Foo(Foo const & other);
...
private:
int a, b, c, d, e;
std::shared_ptr<Bla> p;
};
Foo::Foo(Foo const & other) {
p.reset(new Bla(*other.p));
// Can I avoid having to write the default copy constructor code below
a = other.a;
b = other.b;
c = other.c;
d = other.d;
e = other.e;
}
Run Code Online (Sandbox Code Playgroud) 我有一个指向动态分配数组的类,所以我创建了复制构造函数和赋值运算符函数.由于复制构造函数和赋值运算符函数执行相同的工作,我从赋值运算符函数调用复制构造函数但得到"error C2082: redefinition of formal parameter".我正在使用Visual Studio 2012.
// default constructor
FeatureValue::FeatureValue()
{
m_value = NULL;
}
// copy constructor
FeatureValue::FeatureValue(const FeatureValue& other)
{
m_size = other.m_size;
delete[] m_value;
m_value = new uint8_t[m_size];
for (int i = 0; i < m_size; i++)
{
m_value[i] = other.m_value[i];
}
}
// assignment operator function
FeatureValue& FeatureValue::operator=(const FeatureValue& other)
{
FeatureValue(other); // error C2082: redefinition of formal parameter
return *this;
}
Run Code Online (Sandbox Code Playgroud) 我继续阅读该swap()操作,例如:
template<class T>
void swap (T &a, T &b)
{
T temp (a);
a = b;
b = temp;
}
Run Code Online (Sandbox Code Playgroud)
当我们处理异常安全时会出现问题.
它有什么问题?此外,我们如何解决它?
我正在测试一些代码,其中std::vector一个类中有一个数据成员.类是既可以复印和活动,并operator=描述实现这里使用复制和交换成语.
如果有两个vectors,比如v1大容量和v2小容量,并被v2复制到v1(v1 = v2),则v1在分配后保留大容量 ; 这是有道理的,因为下一次v1.push_back()调用不必强制新的重新分配(换句话说:释放已经可用的内存,然后重新分配它来增长向量没有多大意义).
但是,如果对具有as数据成员的类进行相同的赋值vector,则行为不同,并且在赋值之后不保留更大的容量.
如果不使用复制operator=和交换习惯用法,并且复制和移动operator=是分开实现的,那么行为就像预期的那样(对于普通的非成员vectors).
这是为什么?我们是否应该遵循复制和交换习惯用法,而是分别实施operator=(const X& other)(复制 op=)和operator=(X&& other)(移动 op=)以获得最佳性能?
这是一个可重复的测试输出与复制和交换成语(注意如何在这种情况下,之后 x1 = x2,x1.GetV().capacity()就是1000,不1,000,000):
Run Code Online (Sandbox Code Playgroud)C:\TEMP\CppTests>cl /EHsc …
重新分配变量时,不会调用析构函数:
Object foo = Object(a,b);
foo = Object(c,d);
Run Code Online (Sandbox Code Playgroud)
因此,析构函数只会在Object(c,d)范围的末尾被调用,这显然会导致问题.现在,在这种特殊情况下,它并没有太多困扰我:它足以声明2个不同的对象:
Object foo1 = Object(a,b);
Object foo2 = Object(c,d);
Run Code Online (Sandbox Code Playgroud)
这样,两个对象的析构函数将在最后被调用.
但是,有一种情况我必须重新分配变量,即在对象构造函数中,例如:
SuperObject(Point point1, Point point2) : delay_object_(DelayObject(0)) {
double distance = distance(point1, point2);
double delay = distance / speed;
delay_object_ = DelayObject(delay);
}
Run Code Online (Sandbox Code Playgroud)
事实上,DelayObject参数不容易计算(在这个例子中我也省略了一些其他段落),我想避免在初始化列表中这样做.
我以为我可以通过将对象放在堆中并显式调用析构函数来强制删除:
SuperObject(Point point1, Point point2) : p_delay_object_(new DelayObject(0)) {
double distance = distance(point1, point2);
double delay = distance / speed;
delete p_delay_object_;
p_delay_object_ = new DelayObject(delay);
}
Run Code Online (Sandbox Code Playgroud)
但这对我来说真的很难看,因为我更喜欢在严格必要的时候使用动态分配.我错过了什么吗?
干杯!
背景: 我有一个复杂的类,有很多变量.我有一个声音和测试的复制构造函数:
Applepie::Applepie( const Applepie ©) :
m_crust(copy.m_crust),
m_filling(copy.m_filling)
{
}
Run Code Online (Sandbox Code Playgroud)
在初始化列表中调用的一些成员变量复制构造函数执行分配.
问题:
我需要创建operator=.我可以简单地执行以下操作,而不是使用赋值而不是初始化列表复制现有的构造函数,释放正在被替换的内存等等,
Applepie& Applepie::operator=( const Applepie ©)
{
if( this != ©)
{
this->~Applepie(); // release own object
new(this) Applepie(copy); // placement new copy constructor
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
换句话说,是毁灭自我后跟一个放置新的复制构造函数在语义上与operator =?
这似乎有可能大大减少重复代码并确认每个变量都已正确初始化,但代价是在分配期间可能会略微降低效率.我错过了一些更加模糊的东西吗?
理由: 我的实际班级有大约30个变量.我担心我的复制构造函数和我的赋值操作符都必须复制所有三十个,并且代码可能会发散,导致两个操作以不同的方式执行操作.
我试图使用数组实现堆栈,但我收到一个错误.
class Stack{
private:
int cap;
int elements[this->cap]; // <--- Errors here
int top;
public:
Stack(){
this->cap=5;
this->top=-1;
};
Run Code Online (Sandbox Code Playgroud)
指示的行有以下错误:
Multiple markers at this line
- invalid use of 'this' at top level
- array bound is not an integer constant before ']' token
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?
template <typename T>
void QVector<T>::append(const T &t)
{
const T copy(t);
const bool isTooSmall = uint(d->size + 1) > d->alloc;
if (!isDetached() || isTooSmall) {
QArrayData::AllocationOptions opt(isTooSmall ? QArrayData::Grow : QArrayData::Default);
reallocData(d->size, isTooSmall ? d->size + 1 : d->alloc, opt);
}
if (QTypeInfo<T>::isComplex)
new (d->end()) T(copy);
else
*d->end() = copy;
++d->size;
}
Run Code Online (Sandbox Code Playgroud)
是什么原因const T copy(t)而不是t通过值传递给方法?这和之间有什么区别:
template <typename T>
void QVector<T>::append(const T t)
{
const bool isTooSmall = uint(d->size + 1) > d->alloc;
if (!isDetached() || isTooSmall) …Run Code Online (Sandbox Code Playgroud) c++ ×10
destructor ×2
vector ×2
arrays ×1
c++11 ×1
class ×1
constructor ×1
deep-copy ×1
exception ×1
performance ×1
qt ×1
shared-ptr ×1
string ×1
visual-c++ ×1