Tho*_*Low 12 c++ constructor initialization
我有一个(对我来说)复杂的对象,有大约20个数据成员,其中许多是指向其他类的指针.所以对于构造函数,我有一个很长的,很复杂的初始化列表.该类还有十几个不同的构造函数,反映了可以创建类的各种方法.这些初始化项目中的大多数在这些不同构造函数之间没有变化.
我担心的是,我现在有一大堆复制(或大部分复制)的代码,如果我需要在类中添加一个新成员,可能无法进入每个构造函数初始化列表.
class Object
{
Object();
Object(const string &Name);
Object (const string &Name, const string &path);
Object (const string &Name, const bool loadMetadata);
Object (const string &Name, const string &path, const bool loadMetadata);
}
Object::Object() :
name(),
parent_index (0),
rowData (new MemoryRow()),
objectFile (),
rows (new MemoryColumn (object_constants::RowName, OBJECTID, object_constants::ROWS_OID)),
cols (new MemoryColumn (object_constants::ColName, OBJECTID, object_constants::COLS_OID)),
objectName (new MemoryColumn(object_constants::ObjName, STRING, object_constants::short_name_len, object_constants::OBJECTNAME_OID)),
parent (new MemoryColumn(object_constants::ParentName, STRING, object_constants::long_name_len, object_constants::PARENT_OID)),
parentIndex (new MemoryColumn(object_constants::ParentIndex, OBJECTID, object_constants::PARENTINDEX_OID)),
childCount (new MemoryColumn (object_constants::ChildCount, INTEGER, object_constants::CHILD_COUNT_OID)),
childList (new MemoryColumn (object_constants::ChildList, STRING, object_constants::long_name_len, object_constants::CHILD_OID)),
columnNames (new MemoryColumn (object_constants::ColumnNames, STRING, object_constats::short_name_len, object_constants::COLUMN_NAME)),
columnTypes (new MemoryColumn (object_constants::ColumnTypes, INTEGER, object_constants::COLUMN_TYPE)),
columnSizes (new MemoryColumn (object_constants::ColumnSizes, INTEGER, object_constants::COLUMN_SIZE))
{}
Run Code Online (Sandbox Code Playgroud)
然后如上所述重复其他构造函数.是否有任何智能方法为此使用默认构造函数,然后修改其他构造函数的结果?
vee*_*efu 14
如何将公共字段重构为基类.基类的默认构造函数将处理大量默认字段的初始化.看起来像这样:
class BaseClass {
public:
BaseClass();
};
class Object : public BaseClass
{
Object();
Object(const string &Name);
Object (const string &Name, const string &path);
Object (const string &Name, const bool loadMetadata);
Object (const string &Name, const string &path, const bool loadMetadata);
};
BaseClass::BaseClass() :
parent_index (0),
rowData (new MemoryRow()),
objectFile (),
rows (new MemoryColumn (object_constants::RowName, OBJECTID, object_constants::ROWS_OID)),
cols (new MemoryColumn (object_constants::ColName, OBJECTID, object_constants::COLS_OID)),
objectName (new MemoryColumn(object_constants::ObjName, STRING, object_constants::short_name_len, object_constants::OBJECTNAME_OID)),
parent (new MemoryColumn(object_constants::ParentName, STRING, object_constants::long_name_len, object_constants::PARENT_OID)),
parentIndex (new MemoryColumn(object_constants::ParentIndex, OBJECTID, object_constants::PARENTINDEX_OID)),
childCount (new MemoryColumn (object_constants::ChildCount, INTEGER, object_constants::CHILD_COUNT_OID)),
childList (new MemoryColumn (object_constants::ChildList, STRING, object_constants::long_name_len, object_constants::CHILD_OID)),
columnNames (new MemoryColumn (object_constants::ColumnNames, STRING, object_constats::short_name_len, object_constants::COLUMN_NAME)),
columnTypes (new MemoryColumn (object_constants::ColumnTypes, INTEGER, object_constants::COLUMN_TYPE)),
columnSizes (new MemoryColumn (object_constants::ColumnSizes, INTEGER, object_constants::COLUMN_SIZE))
{}
Run Code Online (Sandbox Code Playgroud)
您的对象构造函数应该看起来更易于管理,现在:
Object::Object() : BaseClass() {}
Object::Object (const string &Name): BaseClass(), name(Name) {}
Object::Object (const string &Name, const string &path): BaseClass(), name(Name), path_(path){}
Object::Object (const string &Name, const bool loadMetadata): BaseClass(), name(Name){}
Object::Object (const string &Name, const string &path, const bool loadMetadata): BaseClass(), path_(path) {}
Run Code Online (Sandbox Code Playgroud)
与Iraimbilanja的答案在本质上类似,但避免添加内部类来访问数据,这可能会影响许多现有代码.但是,如果您已经有了类层次结构,则可能很难将其分解为基类.
Kni*_*chi 11
现在几年后我们有C++ 11.如果你可以在你的项目中使用它,你有两个选择:
当公共初始化值仅在运行时已知时,您可以使用委托构造函数,这意味着一个构造函数调用另一个构造函数.
// function that gives us the init value at runtime.
int getInitValue();
class Foo
{
const int constant;
int userSet;
public:
// initialize long member list with runtime values
Foo()
: constant(getInitValue())
, userSet(getInitValue())
{}
// other constructors with arguments
Foo( int userSetArg)
: Foo()
{
userSet = userSetArg;
}
};
Run Code Online (Sandbox Code Playgroud)
或者,如果在编译时已知其值,则可以直接在类定义中初始化成员.
class Foo
{
const int constant = 0;
int userSet = 0;
public:
Foo( int userSetArg) : userSet(userSetArg){}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
是的,这是可能的.
为简单起见,我假装原始代码是:
class Foo {
public:
Foo() : a(0), b(1), x() { }
Foo(int x) : a(0), b(1), x(x) { }
int get_a() const { return a; }
int get_b() const { return b; }
int get_x() const { return x; }
private:
int a, b, x;
};
Run Code Online (Sandbox Code Playgroud)
然后,重构的代码是:
class Foo {
public:
Foo() : x() { }
Foo(int x) : x(x) { }
int get_a() const { return common.a; }
int get_b() const { return common.b; }
int get_x() const { return x; }
private:
struct Common {
Common() : a(0), b(1) { }
int a, b;
} common;
int x;
};
Run Code Online (Sandbox Code Playgroud)