如何避免在C++中使用Getters/Setter?

Kev*_*217 4 c++

我理解为什么我们应该避免使用getter/setter,但我不知道如何避免使用它们.

例如,我有三个类如下,

  1. A(private: point_B)
  2. B(private: point_C)
  3. C(private: val_C)

A有一个私有成员point_B,它是一个指向的指针B,并且B还有一个私有成员point_C,它是一个指向的指针C.并C具有私人int价值val_C.

如何访问val_CA

更新:

在这种情况下,

  1. A是一个叫做的类state,它有地址point_B.
  2. B是一个名为的类node,它有一个指针调用pointer_C.
  3. C是一个名为的类base_file,它有两个派生类,叫做filedirectory.

更新2:

Ty伙伴们为你提供帮助.你们当中有些人真的想要帮助而不是像一个知道一切的人那样行事.我很感激.Sry我不能在这里发布整个作业,因为即使没有文件也太大了.如果你们明天有兴趣,我会在这里发表教授的答案.

更新3:

请在这里找到参考 正确的做法是让实现指定类.

更新4:

答案是不要在每个类中访问私有值,而是实现使用它们的函数.这就解释了为什么首先把它们变成私人的.

Jer*_*ner 9

可能需要稍作澄清 - 不应该不惜一切代价避免吸气剂和固定剂; 他们有自己的位置.人们说应该避免的原因是因为良好的面向对象程序设计的一个目标是封装 - 也就是说,每个类应该尽可能保持其自身实现的细节,以便该类的用户不要我们需要知道(或关心)课程的实施方式.随着程序变得越来越大,越来越复杂,这变得越来越重要,因为人类程序员只能立刻在他/她的头脑中保留这么多细节,如果程序员必须记住C类工作的一切,同时编写/调试类A,这是一个额外的/不必要的认知负担,在某些时候会导致程序员的大脑爆炸.

因此,回到主要问题 - 如何避免getter和setter - 这样做的方法是在更高的抽象级别定义类的接口而不是状态变量的简单存储库.(毕竟,如果你想要一个简单的状态变量集合,根本就没有理由使用C++类,你可以简单地声明一个C风格的结构)

例如,如果您的C类旨在表示一个老虎机,那么与C类的不良接口可能包含许多getter和setter,如下所示:

int getNumCoins() const {return numCoins;}
void setNumCoins(int newCoinCount) {numCounts = newCoinCount;}
void setDisplayedResult(const string & displayStr) {result = displayStr;}
int getDisplayedResult() const {return result;}
Run Code Online (Sandbox Code Playgroud)

...而被迫使用C类的可怜程序员必须编写如下代码:

playersWallet--;  // take a coin out of the player's wallet
c.setNumCoins(c.getNumCoins()+1);  // insert the coin into the machine
string newResult = "10 J A";   // somehow figure out what the machine should display
c.setDisplayedResult(newResult);  // and make the machine display it
if (c.getDisplayedResult() == "7 7 7")
{
   cout << "YOU ARE WINNER!" << endl;
   int numCoinsWon = 5000;  // jackpot!
   c.setNumCoins(c.getNumCoins()-numCoinsWon);  // deduct from machine's balance
   playersWallet += numCoinsWon;  // add to player's balance
}
[... and so on...]
Run Code Online (Sandbox Code Playgroud)

请注意,在上面的代码中,程序员必须考虑老虎机的所有内部机制,并编写自己的代码来处理其操作的每个步骤.另一方面,通过良好的封装,老虎机的公共界面将更简单,更不透明,如下所示:

// returns the number of coins the player won on this round
int pullTheBigLever();
Run Code Online (Sandbox Code Playgroud)

...并且使用此API的程序员可能会编写如下代码:

playersWallet += (c.pullTheBigLever() - 1);  // -1 for the coin the player put in
Run Code Online (Sandbox Code Playgroud)

请注意,只有一行代码,并且程序员根本不需要考虑老虎机内部的工作原理.这避免了爆炸 - 程序员 - 脑 - 综合症,同样重要的是,它意味着您(或其他人)可以稍后返回并更改老虎机如何工作的私有实现,而不会破坏与老虎机交互的代码.

那么什么时候吸气剂和固定剂可以接受?答:当真的没有任何更高级别的抽象时.如果您正在编写代表灯光开关的类,那么只需检查开关的当前位置,或为其指定新位置,就可能是您需要的所有功能.但是在许多(大多数?)情况下,您正在实现比这更复杂的功能,并且您可以隐藏在公共接口后面的复杂性越多,该类(包括您)的更快乐的用户就越多.