我们刚刚在CS课程简介中开始讨论课程,而我对如何知道变量何时为私有不知所措。今天我们有一个实验,这是.h文件包含的内容: (包含以下代码的类称为personType)
class PersonType {
public:
void print() const;
//Function to output the first name and last name
//in the form firstName lastName.
void setName(string first, string middle, string last);
//Function to set firstName and lastName according
//to the parameters.
//Postcondition: firstName = first; lastName = last
string getMiddleName() const;
//function to return the middle name
//Postcondition: the value of middlename is returned.
string getFirstName() const;
//Function to return the first name.
//Postcondition: The value of firstName is returned.
string getLastName() const;
//Function to return the last name.
//Postcondition: The value of lastName is returned.
personType(string first = "", string middle = "", string last = "");
//Constructor
//Sets firstName and lastName according to the parameters.
//The default values of the parameters are null strings.
//Postcondition: firstName = first; lastName = last
private:
string firstName; //variable to store the first name
string middleName; //variable to store middle name
string lastName; //variable to store the last name
};
在int main中,我自己声明了一个名为personType的类的实例;
对象本身是否可以访问这些私有变量,因为它属于包含私有变量的同一类的一部分?在什么情况下我将无法访问这些私有变量?
答案 0 :(得分:3)
属于PersonType
的任何方法都可以访问私有变量,例如string PersonType::getLastName() const
任何其他代码,包括main(),将无法访问这些变量。
void main()
{
PersonType myself;
myself.getLastName(); // OK!
std::cout << myself.lastName; // ERROR! lastName is private
}
答案 1 :(得分:3)
可以从类定义内编写的代码以及该类成员的所有类外定义中访问private
成员(无该类或在该类的任何实例上)。
这特别意味着,无论您在何处实现PersonType
的方法,它们都可以访问其体内的私有成员。
默认情况下,任何其他代码都不能访问private
成员(没有friend
声明)。
尤其是如果您在PersonType person;
中创建对象main
,则不能使用person.firstName
。不过,您可以在PersonType::setName
的实现中执行相同的操作,也可以在firstName
的实现中使用隐式实例的PersonType::setName
。
可访问性并不特定于类的某些实例。成员名称所使用的代码只是上下文中的问题。成员是否被称为firstName
,person.firstName
,this->firstName
或任何其他方式。在成员函数中,person
是该类的当前实例还是其他实例也无关紧要。
每次编译器在代码中遇到一个名称时,它都会弄清楚该名称所指的声明。然后,可访问性检查将查看名称出现的上下文,并将其与名称查找的结果进行比较,以根据上述规则确定是否应允许访问。
答案 2 :(得分:1)
好,要知道它是否是私有的,您只需要检查它是否在类声明的private
部分中即可:-)
但是,在此基础上扩展,对象(例如myself
)将始终有权访问其私有成员(以及该对象的 other 对象的私有成员)类,假设它可以看到实际的对象本身)。私有通常是(a),旨在防止类之外直接访问它们。
例如,这种预防措施包括尝试通过myself.firstName = "Pax"
函数执行类似main
的操作。
从外部获得该访问级别的通常方法是在类中提供getter和/或setter。使用这些功能,您可以执行以下操作:
这就是您发布的代码中的get*
和set*
方法的用途,尽管我本人会为吸气剂返回常量引用-复制仅可读取的内容毫无意义:
const string &PersonType::getFirstName() const { return firstName; }
const string &name = pt.getFirstName(); // to just use it as is.
string name = pt.getFirstName(); // to get a modifiable copy.
(a)标记为friend
的东西可以绕过这种保护,但是我在这里不作介绍,这会不必要地使答案复杂化。您可能还需要研究protected
,这允许子类访问成员(私有成员是子类的禁区),同时仍然可以保护它们免受继承层次结构之外的影响。
答案 3 :(得分:0)
personType
的每个实例都可以访问其自己的类私有变量的副本。它还可以访问其他相同类型实例的私有变量。
非personType
变量和函数将看不到那些变量。其中包括您可能从personType
派生的任何类的类型的变量。
答案 4 :(得分:0)
对象本身是否可以访问这些私有变量,因为它属于包含私有变量的同一类?
这是从将对象视为可以访问事物的角度出发的。对于“访问”的某些含义,这种观点可能很有用。但是,当“访问”的含义涉及访问说明符(public
,protected
和private
)时,将代码视为具有访问权限会更有用,而不是对象。
实现类的代码可以访问该类的private
详细信息。其他代码则没有。特别是,main
函数中的代码无法访问任何类的任何私有详细信息。
(friend
关键字可以更改某些内容,但不能更改。如果声明为friend
的内容不能合理地视为实现的一部分,则它可能与{ {1}}。)
答案 5 :(得分:0)
对象本身是否可以访问这些私有变量,因为它属于包含私有变量的同一类?
是的。每个实例都有自己的变量副本(除非您将其声明为static
,但这可能是另一个话题了)。因此,如果您有一个对象:
PersonType person;
可以想到的是这些变量:
person.firstName
person.middleName
person.lastName
并且,为了覆盖我的所有基础知识,这些内容可以在课程的内部使用。因此,请执行以下功能:
string getMiddleName() const;
此功能的实现将有权访问所有私有变量。因此,例如:
string PersonType::getMiddleName() const {
return middleName; // if this is called from person (that is, person.getMiddleName())
// then "middleName" here is person.middleName
}
在这里,person.getMiddleName()
可以访问person.middleName
。
在什么情况下我将无法访问这些私有变量?
大多数其他情况下,函数都不属于类PersonType
的一部分。但是,为了清楚起见,我将给出一些示例。
int main() {
PersonType person;
// bad
person.middleName;
return 0;
}
在这里,您无法访问person.middleName
,因为main()
不是PersonType
的一部分。它是main()
,i。 e。另一个功能。一般的经验法则是,如果它不是类的一部分,则不能访问私有变量。
void function(PersonType person) {
person.middleName; // still can't do it
}
此处,function()
不是PersonType
的一部分,因此它无权访问middleName
。
此规则只有一个例外,即无法访问类外部的私有变量,即friend
functions。要创建friend
函数,必须稍微修改标题:
class PersonType {
public:
friend void friendFunction(PersonType person);
//...
};
现在,friendFunction()
可以访问私有数据成员:
void friendFunction(PersonType person) {
person.middleName; // it's fine. We're friends
}
朋友功能的最常见用法是使用名为"operator overloading"的高级主题,您的课程几乎肯定会最终覆盖该主题。
无论如何,与此同时,请这样考虑:它是班级的一部分吗?它可以访问私人成员。是班上的朋友吗?它还可以访问私人成员。还有其他人吗?不,它无法访问私有数据成员。