假设我有会员:
char* name;
向该成员编写 getter 函数时,这是正确的方法吗:
char* getName(){
return name;
}
但是当我们这样做时,现在这个类的用户可以在没有setter的情况下更改名称,因为用户拥有指向堆变量的指针。
我想到了这个解决方案:
char* getName(){
char* otherName;
otherName = new char[10];
strcpy(otherName, name);
return otherName;
}
但是现在,由于该函数创建了一个堆变量,因此用户可能会忘记删除该堆变量,并且它将成为垃圾。这就是为什么这个实现也感觉不是为该成员实现 getter 函数的正确方法。
我该如何实施?
如评论中所述,使用
std::string
而不是 char 数组。例如
class Person {
std::string name;
public:
Person(std::string name) : name(name) { }
// When called on a const Person object,
// we return a copy of the name.
std::string get_name() const { return name; }
// When called on a non-const Person object,
// we return a reference, allowing name to be changed.
std::string& get_name() { return name; }
};
如果您仅限于使用 char 数组,您仍然可以使用它。
class Person {
char *name;
public:
Person(char *n) : name(new char[strlen(n)+1]) {
strcpy(name, n);
}
// When called on a const Person object,
// we return a copy of the name.
char *get_name() const {
char *n = new char[strlen(name) + 1];
strcpy(n, name);
return n;
}
// When called on a non-const Person object,
// we return a reference, allowing name to be changed.
char*& get_name() { return name; }
};
但是现在您必须定义构造函数并按照 三/五/零规则处理复制和移动语义。
class Person {
char *name;
public:
Person(char *n) : name(new char[strlen(n) + 1]) {
strcpy(name, n);
}
~Person() { delete[] name; }
Person(const Person& other)
: name(new char[strlen(other.name) + 1])
{
strcpy(name, other.name);
}
Person& operator=(const Person& other) {
if (&other == this) return *this;
name = new char[strlen(other.name) + 1];
strcpy(name, other.name);
return *this;
}
Person(Person&& other) : name(other.name) {
other.name = nullptr;
}
Person& operator=(Person&& other) {
name = other.name;
other.name = nullptr;
return *this;
}
char *get_name() const {
char *n = new char[strlen(name) + 1];
strcpy(n, name);
return n;
}
char*& get_name() { return name; }
};
随心所欲,但我选择基于
std::string
的解决方案。