私有变量的范围

时间:2019-11-22 23:58:03

标签: c++

我们刚刚在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的类的实例;

对象本身是否可以访问这些私有变量,因为它属于包含私有变量的同一类的一部分?在什么情况下我将无法访问这些私有变量?

6 个答案:

答案 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

可访问性并不特定于类的某些实例。成员名称所使用的代码只是上下文中的问题。成员是否被称为firstNameperson.firstNamethis->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)

  

对象本身是否可以访问这些私有变量,因为它属于包含私有变量的同一类?

这是从将对象视为可以访问事物的角度出发的。对于“访问”的某些含义,这种观点可能很有用。但是,当“访问”的含义涉及访问说明符(publicprotectedprivate)时,将代码视为具有访问权限会更有用,而不是对象

实现类的代码可以访问该类的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"的高级主题,您的课程几乎肯定会最终覆盖该主题。


无论如何,与此同时,请这样考虑:它是班级的一部分吗?它可以访问私人成员。是班上的朋友吗?它还可以访问私人成员。还有其他人吗?不,它无法访问私有数据成员。