有没有办法通过 main 函数访问受保护的向量大小而不将其公开?

Posted

技术标签:

【中文标题】有没有办法通过 main 函数访问受保护的向量大小而不将其公开?【英文标题】:Is there a way to access protected vector size via main function without turning it to public? 【发布时间】:2019-12-07 13:38:50 【问题描述】:

我最近一直在做一个 Shape 程序(你们中的一些人可能还记得我关于这个的其他问题...;/)我有一个小问题我想解决。

在我的 Menu 类中,它包含与菜单相关的所有功能。我有一个 unique_ptr 向量,它的类型是我的基类 Shape ,它包含所有新创建的对象(圆形、矩形等)

protected:
    vector<unique_ptr<Shape>> _shapes;

我想要创建的函数之一应该是根据其索引更改给定形状中变量的值。为此,我打算将矢量打印给用户,然后让他选择要更改的形状的索引。

void Menu::printShapes() const

    int i = 0;
    for (auto p = _shapes.begin(); p != _shapes.end(); p++, i++)
    
        cout << i + " ";
        (*p)->printDetails();
        cout << endl;
    

问题在于我的主程序将使用我的菜单功能。因为我不希望用户能够输入向量之外的值,所以我必须检查给定的输入是否介于 0 和向量的大小之间。但是如果不公开矢量或从 printShapes() 函数返回语句,我就无法从我的主函数访问此信息,这将使代码变得混乱且不直观。

所以我的问题是:有没有办法在不进行上述更改的情况下从主函数的菜单函数中找到向量的大小?因为最后我希望能够只做menu.printShapes() 然后让用户选择他想要改变的形状的索引

这是我目前的主要功能:


    Menu menu;
    int input = 0, wait = 0;
    while (input != 4)
    
        cout << "1: Add New Shape: " << endl;
        cout << "2: Modify Existing Shape: " << endl;
        cout << "3: Delete All Shapes: " << endl;
        cout << "4: Exit: " << endl;
        while (input < MIN || input > MAX)
        
            cin >> input;
            cin.ignore(numeric_limits<streamsize>::max(), '\n');
            std::cin >> wait;
        
        switch (input)
        
            case 1:
            
                cout << "1: Circle: " << endl;
                cout << "2: Rectangle: " << endl;
                cout << "3: Triangle: " << endl;
                cout << "4: Arrow: " << endl;
                while (input < MIN || input > MAX)
                
                    cin >> input;
                    cin.ignore(numeric_limits<streamsize>::max(), '\n');
                    std::cin >> wait;
                
                menu.createShape(input);
            
            case 2:
            
                /*
                I want to be able to access the size of the vector from here
                So I could do something like that:
                menu.printShapes();
                while (input < 0 || input > vectorSize)
                
                    :Get the index of the shape that the user wants to modify
                
                Instant of doing
                size = menu.printShapes();
                */
            
        
    

【问题讨论】:

有很多方法(查找术语getter),但您为什么要这样做?也许您应该更多地从行为的角度来考虑您的类,而不是变量和函数的简单容器? 我不明白你在这里想要达到的目标。相关信息太少,令人分心的东西太多。例如,删除所有形状的东西,当问题是索引是否有效时,向量存储的内容无关紧要。另外,你能展示你想要改进的工作代码吗?有了这个,最好把它带到 codereview.stackexchange.com。 @Someprogrammerdude 可悲的是,我被要求这样(带有菜单类)来帮助我并了解多态性等等。 不,您只需定义 size_t Menu::shapes_count() const return _shapes.size(); ;不涉及额外的变量。而且您不需要“保存”该值 while (input &lt; 0 || input &gt; menu.shapes_count()) 我的意思是你必须以某种方式获得价值。我真的不明白你的困惑或问题。对于minimal reproducible example,这个问题的信息太多,而对于代码审查来说太少,而且它在错误的站点上。 【参考方案1】:

你想太多了。

你只需要添加一个返回向量当前大小的公共函数:

// Declaration in your class
size_t numberOfShapes() const;

// Definition
size_t Menu::numberOfShapes() const

   return _shapes.size();

。然后,当您想知道大小时,调用该函数。

menu.printShapes();
while (input < 0 || input > menu.numberOfShapes())

   // Get the index of the shape that the user wants to modify

简单!

顺便说一句,我想你的意思是&gt;=,而不是&gt;

【讨论】:

【参考方案2】:

你至少有几个选择;取决于 modify-existing-shape 操作的细节。

最简单的方法可能是让您的 Menu 类型公开一个方法来告诉您它正在管理多少个形状。我同意你不应该公开矢量,因为程序不需要特别知道它是一个矢量,但是如果“知道菜单正在管理多少现有形状”是一个要求(它似乎是)然后公开它看起来很合理。

或者,根据修改操作的返回类型,您可以返回可选或变体。如果您有 7 个形状并且我要求您修改第 6 个,那么您可能会告诉我它有效或者可能是新尺寸,但如果我要求您修改第 9 个,您可能会告诉我这是一个无效的索引。

区别在于是否有义务通知呼叫者并提出有效的问题,或者您是否希望更健壮并回答和处理更广泛的问题。我不认为在这种情况下它有很大的不同,但我倾向于第二种解决方案,因为它意味着 any 潜在的调用者受到保护,而不是 all 然后必须检查计数然后自己进行验证。

【讨论】:

以上是关于有没有办法通过 main 函数访问受保护的向量大小而不将其公开?的主要内容,如果未能解决你的问题,请参考以下文章

通过公共方法访问受保护的属性

PHP 从静态方法访问对象的受保护属性

有没有办法仅通过类型来获取向量的字节大小?

获取指向基类受保护成员函数的函数指针

受保护和没有访问修饰符之间的区别[关闭]

无法访问受保护的成员[重复]