- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我知道有很多关于这个主题的帖子,但我找不到任何帖子来完全回答我的问题。
假设我有一个基类和一个派生类,我为它实现了一个 CCtor 和一个赋值运算符,如下所示:
class Base {
char * name;
....
Base(const Base& other) :name(nullptr) { *this = other }
void operator=(const Base& other) { ... Deep copy of name }
}
class Derived : public Base {
....
Derived(const Derived& other) { *this = other ; }
void operator=(const Derived& other) {
Base::operator=(other);
.....
}
现在我对这个设计有一些疑问。
编辑:澄清一下,设计是我在项目中得到的。我有指针,所以我必须使用深拷贝。
最佳答案
Is this the right design for the situation?
不,通常不会。更惯用的方法是停止手动管理内存,如 char* name
并使用 std::string
或其他可以做正确事情的类型:
Class Base {
std::string name;
....
Base(const Base& other) = default;
Base& operator=(const Base& other) = default;
};
(请注意,赋值运算符应返回对类的引用,而不是 void
)。
或者将内存管理封装在专门为此目的设计的类中(但 std::string
已经是那种类型)。
如果你真的真的需要用愚蠢容易出错的方式来做,那么实现你的复制构造函数来进行复制:
Base(const Base& other) { / * deep copy of name */ }
然后将赋值实现为 copy-and-swap :
Base& operator=(const Base& other)
{
Base tmp(other);
this->swap(tmp);
return *this;
}
这意味着您需要一个廉价的、不会抛出的 swap(Base&)
成员函数。
无论如何,派生类型的复制构造函数都是愚蠢的。您有一个正确的基类复制构造函数,因此它应该是:
Derived(const Derived& other) : Base(other) { }
并且赋值可以使用基础赋值:
Derived& operator=(const Derived& other)
{
Base::operator=(other);
return *this;
}
但是手动编写这些是不必要的,你可以只默认它的复制操作,无论如何都会做正确的事情:
class Derived : public Base {
public:
Derived(const Derived&) = default;
Derived& operator=(const Derived& ) = default;
If i have a third class, between the base and the derived class, but it only contains primitive types, where shoud I copy them ? E.G. use the default assignment operator of the second class ? build a new one? only copy them on the third level ?
您还应该使用 = default
定义该类的复制构造函数和赋值运算符。一旦您使 Base
可以安全地以正确的行为进行复制,编写其他类来使用它就很简单了。默认行为将做正确的事。如果您需要对动态分配的内存等未由 RAII 类型正确管理的内容进行特殊处理,则只需手动定义这些操作。
I could similary call the base class CCtor inside the derived class CCtor, instead of the assignment operator. What's the difference?
如果你想复制构造,那么使用复制构造函数,而不是赋值。为工作使用正确的函数。
关于c++ - 在派生类中使用基类 Copy CTOR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50607137/
我似乎遇到过一个例子,其中默认的移动构造函数似乎根据情况被视为用户声明的和非用户声明的: struct Foo { int a; Foo():a(42){}; //Foo(co
我在我的代码中定义了一个复制构造函数,它正在初始化正在创建的对象的数据成员。现在,如果我只需要更改几个变量的值,我正在编写一个新的复制构造函数。所以我的问题是,我是否可以只初始化特定的不同数据成员,而
为什么从 bar 返回时调用复制构造函数而不是移动构造函数? #include using namespace std; class Alpha { public: Alpha() { cout
我很抱歉这个晦涩的标题,不知道如何更好地表达它。 考虑以下继承层次结构: struct A { A(int) {} }; struct B : virtual A { B() : A(
为什么 var b = new B() 首先进入 static B() .ctor 而不是 static A () .ctor 而不是像实例构造函数那样反之亦然 (public A() 而不是 pub
我正在使用 SourceryGpp lite for arm 开发一个应用程序和一个库。 我没有使用标准库或默认启动文件。因此,要调用我正在对以下代码执行的全局 ctrs: ldr r0,=__cto
class Foo { public: Foo() { Foo(1)} Foo(int x, int y = 0):i(x) {} private: int i; } 任何人都可以给我
在下面的代码中,我想移动构造一个没有可用移动构造函数的对象: class SomeClass{ public: SomeClass() = default; SomeClass(con
这在 C++11 中似乎不起作用: class B : public A { public: B(const A& a) : A(a) // parent constr
我们如何在 F# 中为不可变结构定义一个仅接受部分字段的构造函数。或者,与 C# 相比,我们如何在 f# 中将结构清零(例如在下面的 c# 示例中调用 this())? c# struct Point
代码 #include using namespace std; #define PF cout class derp { public: derp() = default
我所拥有的基本上是一个 std::map,其中包含指向 Views 的指针。 std::map myViews; template bool addView( string assocName ,
我有下面的代码来测试std::string类的copy ctor和move ctor,结果让我吃惊,move ctor慢了~1.4倍比抄袭者。 据我了解, move 构造不需要分配内存,对于std::
我有一个静态构造器,它从我的配置服务器获取配置并设置一个静态变量。 我有一个常规构造函数,它根据该配置实例化一些属性。 这是我类(class)的一个例子: public class MyClass {
这个问题已经有答案了: How do I call New-Object for a constructor which takes a single array parameter? (2 个回答)
我有一个小问题,我不确定这是一个编译器错误,还是我这边的愚蠢。我有这个结构: struct BulletFXData { int time_next_fx_counter; int next_fx
如果我有一个同时定义了复制构造函数和移动构造函数的类,我是否需要使复制构造函数的参数const? 最佳答案 如果copy ctor取的不是const引用参数而是引用参数,那么你将无法copy构造con
我想知道是否有一种安全编程实践可以在这种微妙的行为发生时提醒编码人员,或者更好的是,首先避免这种行为。 struct A 的用户可能没有意识到没有 move 构造函数。在他们尝试调用不存在的 ctor
当类具有普通构造函数和/或普通析构函数时,C++ 标准定义了一些非常具体的行为。 例如,根据标准的 §3.8/1: The lifetime of an object of type T ends w
如果我想禁止复制构造/赋值那么是: class foo { public: foo(const foo&) = delete; foo& operator = (const foo&) =
我是一名优秀的程序员,十分优秀!