【问题标题】:How to write a private attribute of a class?如何写一个类的私有属性?
【发布时间】:2019-09-20 04:43:27
【问题描述】:

我正在研究一个包含另一个类的对象数组的类。但我不能这样做。这是我尝试使用的代码的简化版本。谁能帮我处理它?

为什么s不能访问自己的数据成员?

任何人都可以展示如何处理这些场景的整个概念吗?

P.S - 仅使用 FRIEND(类或函数)关键字。不允许继承。

class Student{
private:
    int roll;
    char name1[15];
};

class Subject  {
private:
    Student s[10];
};

int main()
{
    Subject s1;
    s1.s[1].roll = 5; // trying to set roll of 1st student
    return 0;
}

我原以为会分配该值,但它有以下错误。 为什么会这样?

错误:“学生主题::s [10]”是私人的 错误:“int Student::roll”是私有的 错误:“学生主题::s [10]”是私有的 错误:“int Student::roll”是私有的

【问题讨论】:

标签: c++ class oop friend


【解决方案1】:

谁能帮助我如何使用它。为什么 s 不能访问它自己的数据成员。

当然可以,但您看到的错误是尝试访问main 中的SubjectStudentprivate 成员的结果。

main 无法访问 private 的成员 SubjectStudent。为了允许main 直接访问成员变量,您必须将成员变量设置为public。另一种选择是添加与private 成员变量对应的public 访问器和修饰符函数。

【讨论】:

    【解决方案2】:

    如果你想将一个属性设为私有但仍打算允许它被设置,那么常用的习惯用法是创建一个“setter”。

    在这种情况下,您需要为每个具有您仍然想要设置的私有属性的类执行两次。

    class Student{
        public:
            void setroll(int newroll)
            {
                roll = newroll;
            }
        private:
            int roll;
            char name1[15];
    };
    
    class Subject  {
        public:
            void setstudentsroll(int newroll, int index)
            {
                /* a good setter would at this point check the index,
                to make sure it does not access beyond the array */
                s[index].setroll(newroll);
            }
        private:
            Student s[10];
    };
    
    int main()
    {
        Subject s1;
        s1.setstudentsroll(5,1); // trying to set roll of 1st student
        return 0;
    }
    

    对于内部情况,可以使用friend 关键字,其中访问代码位于可以命名的类中。但是,我认为这是您遇到的实际问题,允许 main() 进行设置无济于事。

    【讨论】:

    • 如果您需要使用friend 解决内壳问题,请告诉我。
    • @RemyLebeau 这种格式化代码的方式有什么好处?
    • @RemyLebeau 请在更改措辞时更加小心。
    • @RemyLebeau 通过“这种格式化方式”,我的意思是三次反引号,而不是缩进 4。我喜欢你改进的缩进,谢谢。但请解释为什么您认为您选择降价是值得编辑的改进。
    • 我现在经常使用移动设备访问 StackOverflow,并且使用带有制表符字符的三重刻度标记进行缩进比使用 4 空格标记更容易在触摸屏键盘上键入,这使得使用制表符用于缩进 PITA 的字符,因为我的键盘喜欢在键入制表符时删除 4 个空格。此外,三重刻度标记更清晰,特别是在指定语法突出显示语言时
    【解决方案3】:

    学生数组被声明为 Subject 类的私有成员。

    不能在类范围之外访问私有成员,这意味着您不能从您的主(或任何其他)函数访问它。

    您的第一个选择是将此数组声明为公共成员。 另一种是使用 getter/setter 来获取/修改该成员

    class Student
    {
    private:
        int roll;
        char name1[15];
    
    public:
        char* getName(void)
        {
            return strdup(this->name1); 
        }
    
        void setRoll(int r)
        {
            this->roll = r;
        }
    };
    
    class Subject
    {
    private:
        Student s[10];
    
    public:
    
        void setStudentRoll(int roll, char *s_name)
        {
            for (int i = 0; i < 10; i++)
            {
                if (strcmp(this->s[i].getName(), s_name) == 0)
                {
                    this->s[i].setRoll(roll);
                    break;
                }
            }
        }
    };
    

    请记住,为了设置学生的滚动成员(也被声明为私有成员),您将遇到同样的问题。

    【讨论】:

    • 您是否尝试从setStudenRoll() 内部设置任何学生滚动?我想你会遇到障碍。
    • 遍历 s[] 数组,将名称与给定名称进行比较(当然,名称成员需要以相同的方式检索)并调用 set_roll(将在学生类中定义为设置它的滚动),为我工作:S
    • 请展示这一点,尤其是在您编写不同类的私有属性而不是朋友的部分。当您记住 OP 似乎很乐意提供索引时,您不想在此处显示的代码可能会变得更容易。
    • 如果提供了索引,我同意它更容易:)。我遍历学生数组并使用 strcmp 匹配学生的姓名(使用 getName 学生班级),当匹配完成后,我使用 setRoll (学生班级)设置学生的卷。
    • 公平就是公平,我确实认为索引是理所当然的。 :-) 但是请注意,这里有些用户会在答案中戳类似这样的小东西,在什么是深度评论中。如果您投了反对票,我不会投反对票,但这些用户可能会投反对票。
    【解决方案4】:

    您被声明为变量并且学生对象具有私有访问说明符。您无法在该类之外初始化变量值。使用 public 你可以在程序的任何地方初始化变量...... 解决方案:

    class Student{
     public:
     int roll;
     char name1[15];
     };
     class Subject  {
     public:
     Student s[10];
     };
     int main()
     {
      Subject s1;
      s1.s[1].roll = 5; // trying to set roll of 1st student 
     return 0;
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 1970-01-01
      • 2013-06-13
      相关资源
      最近更新 更多