在 set 方法中传递 get 方法
Passing a get method in a set method
我是 OOP 的新手,正在尝试自学。
这个简单的(我觉得很简单,但是我有心理障碍)练习逻辑实现不太清楚:
- 创建一个
Employee
class,包含 name
、surname
和 salary
字段
- 创建 2 名员工并在增加 10% 前后打印他们的工资。
所以,这是我的文件:
// employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <string>
using std::string;
class Employee {
private:
string name;
string surname;
float salary;
public:
Employee(string,string,float);
void setName(string);
void setSurname(string);
void setSalary(float);
string getName();
string getSurname();
float getSalary();
};
#endif // EMPLOYEE
employee.cpp
#include "employee.h"
Employee::Employee(string n,string c,float stip) {
Employee::setName(n);
Employee::setSurname(c);
Employee::setSalary(stip);
}
void Employee::setName(string n){
name=n;
}
void Employee::setSurname(string c){
surname=c;
}
void Employee::setSalary(float stip){
salary=(stip>=0)?stip:0;
}
string Employee::getName(){
return name;
}
string Employee::getSurname(){
return surname;
}
float Employee::getSalary(){
return salary;
}
increase.h
#ifndef INCREASE_H
#define INCREASE_H
namespace Increase {
const float inc2017=1.1;
}
#endif // INCREASE_H
关于主文件,我考虑了 2 种可能性:
1) 使用变量本地保存工资
float prov=a.getSalary();
a.setSalary(prov*Increase::inc017);
2)在set方法中传递get方法:
a.setSalary(a.getSalary()*Increase::inc2017);
哪个更好?
2号在逻辑上是正确的还是我这样绕过封装?
(我知道在这个小问题中没有必要使用命名空间头,但我正在朝着更大的项目努力,我想为此做好心理准备)
回答您的具体问题:设置新值时不使用临时变量是完全可以的。
一旦值被提取出来,它就不可能破坏封装,因为我们谈论的是根本不接触对象内部的代码。
评论中建议的一个解决方案,可以使 class 多一点 closed/specific,将是一个专用的 "increase by" 成员函数,但这是否由您决定class 应该有这个功能内幕,或者你是否想将增加委托给另一个组件。
根据经验,如果 class 没有围绕其成员的不变量的额外逻辑,则可以使成员成为 public - 这样你就可以摆脱吸气剂和设置器,您的问题会自行回答。
您的 getter 函数是:
float Employee::getSalary(){
return salary;
}
请注意,此函数正在返回会员薪水的副本。该函数的使用者无法改变成员变量 salary
的值。
如果您的 getter 函数返回对 salary
的引用,用户可能已经能够更改 salary
成员变量的值,从而破坏封装。
float& Employee::getSalary(){
return salary;
}
因此,您不必担心破坏您编写的 getter 函数的封装。
我是 OOP 的新手,正在尝试自学。
这个简单的(我觉得很简单,但是我有心理障碍)练习逻辑实现不太清楚:
- 创建一个
Employee
class,包含name
、surname
和salary
字段 - 创建 2 名员工并在增加 10% 前后打印他们的工资。
所以,这是我的文件:
// employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include <string>
using std::string;
class Employee {
private:
string name;
string surname;
float salary;
public:
Employee(string,string,float);
void setName(string);
void setSurname(string);
void setSalary(float);
string getName();
string getSurname();
float getSalary();
};
#endif // EMPLOYEE
employee.cpp
#include "employee.h"
Employee::Employee(string n,string c,float stip) {
Employee::setName(n);
Employee::setSurname(c);
Employee::setSalary(stip);
}
void Employee::setName(string n){
name=n;
}
void Employee::setSurname(string c){
surname=c;
}
void Employee::setSalary(float stip){
salary=(stip>=0)?stip:0;
}
string Employee::getName(){
return name;
}
string Employee::getSurname(){
return surname;
}
float Employee::getSalary(){
return salary;
}
increase.h
#ifndef INCREASE_H
#define INCREASE_H
namespace Increase {
const float inc2017=1.1;
}
#endif // INCREASE_H
关于主文件,我考虑了 2 种可能性:
1) 使用变量本地保存工资
float prov=a.getSalary();
a.setSalary(prov*Increase::inc017);
2)在set方法中传递get方法:
a.setSalary(a.getSalary()*Increase::inc2017);
哪个更好?
2号在逻辑上是正确的还是我这样绕过封装?
(我知道在这个小问题中没有必要使用命名空间头,但我正在朝着更大的项目努力,我想为此做好心理准备)
回答您的具体问题:设置新值时不使用临时变量是完全可以的。
一旦值被提取出来,它就不可能破坏封装,因为我们谈论的是根本不接触对象内部的代码。
评论中建议的一个解决方案,可以使 class 多一点 closed/specific,将是一个专用的 "increase by" 成员函数,但这是否由您决定class 应该有这个功能内幕,或者你是否想将增加委托给另一个组件。
根据经验,如果 class 没有围绕其成员的不变量的额外逻辑,则可以使成员成为 public - 这样你就可以摆脱吸气剂和设置器,您的问题会自行回答。
您的 getter 函数是:
float Employee::getSalary(){
return salary;
}
请注意,此函数正在返回会员薪水的副本。该函数的使用者无法改变成员变量 salary
的值。
如果您的 getter 函数返回对 salary
的引用,用户可能已经能够更改 salary
成员变量的值,从而破坏封装。
float& Employee::getSalary(){
return salary;
}
因此,您不必担心破坏您编写的 getter 函数的封装。