我对C ++比较陌生,我认为我的问题最好通过例子来理解。在我的头文件中,假设我有
class myClass{
public:
double getVar1();
void setVar1(double newVar1);
void copyVar1(myClass* dat);
private:
double var1;
};
在我的实现.cc文件中,在实现copyVar1方法时,我应该
void myClass::copyVar1(myClass* dat){
var1 = dat->var1;
}
或
void myClass::copyVar1(myClass* dat){
var1 = dat->getVar1();
}
在第二种情况下,我使用getter方法。两者都可以在Visual C ++中正常工作,但我想知道在实践中哪个更好用。
感谢您的评论!
答案 0 :(得分:4)
最佳做法?重载赋值运算符而不是编写方法。
myClass & myClass::operator=(const myClass & dat)
{
var1 = dat.var1; // or dat.getVar1()
return *this;
}
至于使用田地或打电话给安装者......这都是个人品味的问题。如果你的吸气剂有一些副作用,那么你可能应该调用它,否则,请使用该字段。
所以,一个大的“取决于”。
答案 1 :(得分:2)
当你在课外时,你应该几乎总是使用getter / setter方法来访问变量,而且通常你必须这样做,因为这是唯一的方法。但是,当你在类中时,你可以使用其中任何一个,如果getter方法什么都不做,只返回变量,它将没有什么区别。
您的决定将取决于您是否在getter方法中执行的操作不仅仅是返回变量,而如果您希望在调用copyVar1
时运行该代码< / strong>即可。如果您不知道,我建议如果您决定更改将来的代码,仍然会使用getter方法。虽然它现在只是直接访问它,但你可能在微观上有更好的性能,但是当你不应该在你不应该调用时,更容易找到调用getter的错误。并且编译器可能最终会进行足够的优化,甚至不会感觉到差异。 :d
答案 2 :(得分:1)
我更喜欢使用setter和getter,如果你改变一些实现细节(例如引入值赋值的验证),你就必须在setter中的一个地方改变它...
答案 3 :(得分:0)
这取决于。许多人会告诉你,使用getters / setter而不是变量对编程错误和更改更加健壮,并减少代码重复。但只要这些getter / setter不是内联函数,你可能会获得很小的性能影响,因为实现必须知道类的内部,为什么不直接使用变量。
答案 4 :(得分:0)
您是否正在尝试编写复制构造函数?当你有setVar1时,为什么需要copyVar1
?如果您正在尝试编写复制构造函数,最好不要使用getter。
myclass(const myclass& other)
{
var1 = other.var1;
}
当你同时拥有getter和setter时,为什么不将var1公开?
答案 5 :(得分:0)
这里没有正确或错误的方法。
但是,假设getVar1()返回值或var1。如果您决定更改var1值的存储方式,那么您需要浏览所有代码并进行更新。使用setter / getter可以将其简化为几种方法。在这种情况下,您应该使用第三个选项:
void myClass::copyVar1(myClass* dat){
setVar1 (dat->getVar1());
}
然后你完全删除对var1的依赖,你可以将var1改为其他东西,copyVar1仍然可以工作。
答案 6 :(得分:0)
正如你所说,两者都正常运作并且完全合法。
从某种意义上说,直接访问成员变量或使用访问器之间的区别在于你在类中定义了一个更强大的“层”;任何层都可以帮助您减少依赖关系。
换句话说,getter方法基本上响应不向外界公开实现细节的要求;比方说,您可能有一天决定不将var1
存储为双倍,而是计算它。因此,访问器为您提供了这种自由:在某种程度上,您可以在不影响其他类的情况下更改实现(即减少依赖性)。
在类本身中使用getter方法的情况也是如此,即,您正在删除类范围内的依赖项,并且您的设计对更改更具弹性。
答案 7 :(得分:0)
提取者和获取者的抽象点是检索方法可能会改变。当您直接访问成员变量时,如果有任何更改,您必须在任何地方更新您的使用情况。但是如果你使用这个函数,那么改变检索变量的方式只需要改变函数。
现在,因为这是同一个类,所以与将变量设置为public相比,它更不用担心,因为您只需要更新这个实现文件(而不是更新类的每个用户,这可能不是如果您有图书馆类可以。)
要看到这一点,请查看突然需要使线程安全的类。现在,您的复印机看起来像
void myClass::copyVar1(myClass * dat)
{
scoped_lock lock(mutex);
var1 = dat->getVar1();
}
如果您总是按功能调用,则无需在其他任何地方修复。如果直接访问变量,那么它看起来像
void myClass::copyVar1(myClass * dat)
{
scoped_lock lock(mutex);
scoped_lock lock2(dat->mutex)
var1 = dat->var1;
}
将“dat”的互斥锁定在dat外部,通常不被认为是一个非常好的设计(如果你让工程师必须记住锁定其他人的对象,那么你就会忘记他们忘记并且不这样做)
同样,如果变量开始存储在数据库中,您也必须处理它。或者,如果变量现在存储在两个不同的变量中并在检索时构造,您可以看到复杂性将如何增加。
但请记住,使用访问器和增变器的设计理念是通过封装来降低潜在的复杂性。有时候你在小型项目(特别是个人项目)上工作,你无意改变课程。直接访问它们可能不那么复杂。不要害怕这样做,只要知道你为什么要做出决定。