分配给 *this 以进行构造函数委托
我正在研究 C++11 中的一些新功能,由于我当前的 GCC 版本,我无法使用构造函数委托。但这让我考虑复制这样的功能:
class A
{
public:
A() : num( 42 ) {}
A( int input ) { *this = A(); num *= input; }
int num;
};
它确实可以编译并正常工作,下面的代码:
A a;
cout << "a: " << a.num << endl;
A b( 2 );
cout << "a: " << b.num << endl;
返回这个,这是正确的。
42
84
显然这是一个非常简单的例子,但是除了内存效率低下(创建了两个A
,一个在被销毁之前被另一个覆盖)之外,还会出现什么问题呢?它确实看起来像代码味道,但我想不出一个真正好的理由。
I was looking at some of the new features in C++11, and due to my current version of GCC I am unable to use constructor delegation. But it got me thinking about replicating the feature like this:
class A
{
public:
A() : num( 42 ) {}
A( int input ) { *this = A(); num *= input; }
int num;
};
It certainly compiles and works fine, the code below:
A a;
cout << "a: " << a.num << endl;
A b( 2 );
cout << "a: " << b.num << endl;
Returns this, which is correct.
42
84
Obviously this is a very trivial example, but other than the memory inefficiencies (two A
's created and one overwritten by the other before being destroyed), what problems could arise? It certainly looks like a code smell, but I can't think of a really good reason why.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您不是用整数初始化对象,而是修改默认初始化的对象。这可能是也可能不是问题。人们经常在一些
init()
函数中分解出常见的东西,以具有与委托 ctor 类似的功能。然而,在某些情况下,这是不希望的/错误的/不可能的:此外,有些人认为这是不好的风格。我个人认为这是不好的风格,因为我认为你应该总是初始化而不是稍后分配,即使对于简单的情况也是如此,因为有一天你忘记了一个重要的情况,然后性能的损失就会让你痛苦。
但是YMMV。
You are not initializing your object with the integer, but modifying a default initialized object. This might or might not be an issue. Quite often people factor common stuff out in some
init()
function to have similar functionality as delegating ctors. However, there are some situations in which this is not desired/wrong/impossible:Additionally, this is just considered bad style by some people. I personally consider it bad style because I think you should always initialize instead of assign later, even for simple cases, since one day you forget it for an important case and then the lost performance bites you.
But YMMV.
您的代码实际上根本不是 C++11。我在想移动构造函数是否可以在这里工作,因为您本质上是将一个 A 移动到另一个 A 中,然后稍微修改它。
与 C++03 一样,您可以通过将所有构造函数放入子类或基类(通常使用受保护或私有继承,因为它是实现细节)来优化您想要在所有构造函数中执行一次的初始化。使用基类:(
您可以修改您的访问权限来品尝)。这里的问题是我只创建了一个“ABase”对象,如果它不仅仅是一个简单的 int 成员,那可能很重要。我非常喜欢继承,因为我然后在 A 中将它用作类成员而不是某个聚合对象的成员,并且我更喜欢这里的继承 protected 或 private,但有时如果基类有我想要公开的成员,我会使用公共继承,但为基类提供受保护的析构函数。这是假设没有 v 表,因此不需要进一步的推导。 (实际上,您可以通过将继承设为虚拟和私有来最终确定 A,但您可能不想这样做)。
Your code is not actually C++11 at all. I was thinking whether move constructors might work here as you are essentially moving one A into another then modifying it slightly.
As with C++03, you can optimise the initialisation you want to perform once in all your constructors either by putting them into a sub-class or a base-class (often with protected or private inheritance as it's an implementation detail). Using a base class:
(You can modify your access permissions to taste). The issue here is I only ever create one "ABase" object and if it has more than just a trivial int member, that might be significant. I quite like the inheritence as I then use it in A as a class member rather than a member of some aggregated object, and I prefer the inheritence protected or private here but sometimes if the base class has members I want to be public, I will use public inheritence but give the base class a protected destructor. This is assuming there is no v-table and thus no further derivation is expected. (You can finalize A here actually by making the inheritance virtual and private but you probably don't want to).