cbr*_*lak 2 c++ copy-constructor member-variables
我有一个带有复制构造函数的简单容器类.
您是否建议使用getter和setter,或直接访问成员变量?
public Container
{
public:
Container() {}
Container(const Container& cont) //option 1
{
SetMyString(cont.GetMyString());
}
//OR
Container(const Container& cont) //option 2
{
m_str1 = cont.m_str1;
}
public string GetMyString() { return m_str1;}
public void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
}
Run Code Online (Sandbox Code Playgroud)
更新(09年9月29日):
其中一些答案写得很好但是他们似乎忽略了这个问题的重点:
这是一个简单的人为例子,讨论使用getter/setter和变量
初始化列表或私有验证器函数实际上不是这个问题的一部分.我想知道这两种设计是否会使代码更容易维护和扩展.
一些ppl在这个例子中专注于字符串,但它只是一个例子,想象它是一个不同的对象.
我不关心表现.我们不是在PDP-11上编程
Ara*_*raK 11
编辑:回答编辑的问题:)
这是一个简单的人为例子, 讨论使用getter/setter和 变量
如果您有一个简单的变量集合,不需要任何类型的验证,也不需要额外的处理,那么您可以考虑使用POD.来自Stroustrup的FAQ:
精心设计的类为其用户提供了一个干净简单的界面, 隐藏其表示并使用户不必了解该表示.如果不应该隐藏表示 - 比如,因为用户应该能够以他们喜欢的方式更改任何数据成员 - 您可以将该类视为"只是一个普通的旧数据结构"
简而言之,这不是JAVA.你不应该写普通的getter/setter,因为它们和它们自己暴露变量一样糟糕.
初始化列表或私有验证器函数实际上不是这个问题的一部分.我想知道这两种设计是否会使代码更容易维护和扩展.
如果要复制另一个对象的变量,则源对象应处于有效状态.这个生病的源对象是如何在第一时间构建的?!构造函数不应该做验证工作吗?是不是修改成员函数负责通过验证输入来维护类不变量?为什么要在复制构造函数中验证"有效"对象?
我不关心表现.我们不是在PDP-11上编程
这是最优雅的风格,但在C++中,最优雅的代码通常具有最佳的性能特征.
你应该使用一个initializer list.在您的代码中,m_str1默认构造然后分配一个新值.你的代码可能是这样的:
class Container
{
public:
Container() {}
Container(const Container& cont) : m_str1(cont.m_str1)
{ }
string GetMyString() { return m_str1;}
void SetMyString(string str) { m_str1 = str;}
private:
string m_str1;
};
Run Code Online (Sandbox Code Playgroud)
@cbrulak你不应该IMO验证cont.m_str1中copy constructor.我所做的就是验证内容constructors.验证copy constructor意味着您首先复制一个不良格式的对象,例如:
Container(const string& str) : m_str1(str)
{
if(!valid(m_str1)) // valid() is a function to check your input
{
// throw an exception!
}
}
Run Code Online (Sandbox Code Playgroud)
您应该使用初始化列表,然后问题变得毫无意义,如:
Container(const Container& rhs)
: m_str1(rhs.m_str1)
{}
Run Code Online (Sandbox Code Playgroud)
Matthew Wilson的Imperfect C++中有一个很棒的部分解释了所有关于成员初始化列表的内容,以及如何将它们与const和/或引用结合使用以使代码更安全.
编辑:显示验证和const的示例:
class Container
{
public:
Container(const string& str)
: m_str1(validate_string(str))
{}
private:
static const string& validate_string(const string& str)
{
if(str.empty())
{
throw runtime_error("invalid argument");
}
return str;
}
private:
const string m_str1;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2772 次 |
| 最近记录: |