在构造函数中做什么(不) [英] What (not) to do in a constructor

查看:108
本文介绍了在构造函数中做什么(不)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想问你关于C ++中构造函数的最佳实践。我不太确定我应该在一个构造函数和什么不应该做。

I want to ask you for your best practices regarding constructors in C++. I am not quite sure what I should do in a constructor and what not.

我应该只使用它的属性初始化,调用父构造函数等?
或者我甚至可以把更复杂的函数放入它们,如读取和解析配置数据,设置外部库a.s.o。

Should I only use it for attribute initializations, calling parent constructors etc.? Or might I even put more complex functions into them like reading and parsing configuration data, setting up external libraries a.s.o.

或者我应该为此写特殊函数? Resp。 init() / cleanup()

Or should I write special functions for this? Resp. init() / cleanup()?

我还想知道,例如,我可以使用 init()时除去共享指针 cleanup()

I figured out yet that for example I can get rid of shared pointers when using init() and cleanup(). I can create the objects on the stack as class attributes and initialize it later while it is already constructed.

如果我在构造函数中处理它,我需要在运行时实例化它。然后我需要一个指针。

If I handle it in the constructor I need to instantiate it during runtime. Then I need a pointer.

我真的不知道该如何决定。

I really don't know how to decide.

推荐答案

复杂的逻辑和构造函数并不总是混合良好,并且有强烈的支持者在构造函数(有原因)。

Complex logic and constructor do not always mix well, and there are strong proponents against doing heavy work in a constructor (with reasons).

基本规则是构造函数应该产生一个完全可用的对象。

The cardinal rule is that the constructor should yield a fully usable object.

class Vector
{
public:
  Vector(): mSize(10), mData(new int[mSize]) {}
private:
  size_t mSize;
  int mData[];
};

这并不意味着一个完全初始化的对象,你可以延迟一些初始化用户不必考虑它。

It does not mean a fully initialized object, you may defer some initialization (think lazy) as long as the user does not have to think about it.

class Vector
{
public:
  Vector(): mSize(0), mData(0) {}

  // first call to access element should grab memory

private:
  size_t mSize;
  int mData[];
};

如果有大量工作要做,您可以选择继续执行一个构建器方法在调用构造函数之前做重工作。例如,假设从数据库检索设置并构建设置对象。

If there is heavy work to be done, you might choose to proceed with a builder method, that will do the heavy work prior to calling the constructor. For example, imagine retrieving settings from a database and building a setting object.

// in the constructor
Setting::Setting()
{
  // connect
  // retrieve settings
  // close connection (wait, you used RAII right ?)
  // initialize object
}

// Builder method
Setting Setting::Build()
{
  // connect
  // retrieve settings

  Setting setting;
  // initialize object
  return setting;
}

如果延迟对象的构造产生显着的好处, 。从示例如果对象抓取了大量的内存,延迟内存采集后任务可能失败可能不是一个坏主意。

This builder method is useful if postponing the construction of the object yields a significant benefit. From example if the objects grab a lot of memory, postponing the memory acquisition after tasks that are likely to fail may not be a bad idea.

这个构建器方法隐含私有构造函数和公共(或朋友)构建器。请注意,有一个Private构造函数对一个类可以做的用法(例如,不能存储在STL容器中)施加了许多限制,因此您可能需要在其他模式中合并。这是为什么这种方法只能在特殊情况下使用的原因。

This builder method implies Private constructor and Public (or friend) Builder. Note that having a Private constructor imposes a number of restrictions on the usages that can be done of a class (cannot be stored in STL containers, for example) so you might need to merge in other patterns. Which is why this method should only be used in exceptional circumstances.

如果你依赖外部事物(文件/ DB),考虑依赖注入,它真的有助于单元测试。

You might wish to consider how to test such entities too, if you depend on an external thing (file / DB), think about Dependency Injection, it really helps with Unit Testing.

这篇关于在构造函数中做什么(不)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆