【问题标题】:Inner Class Accessing Parent from a Global Variable内部类从全局变量访问父级
【发布时间】:2021-03-02 18:14:08
【问题描述】:

如何改进以下代码的结构?

我有一个嵌套类。我想访问可用作全局向量的父类。丑陋的部分是当我将父类的索引存储在子类中时。我能做得更好吗?

vector<A> vec;

struct A
{
    int val;
    struct B
    {
        size_t id; // Index of the parent in the global vector. Doesn't look good!
        void func()
        {
            cout << vec[id].val;
        }
    };
    B b;
};

int main()
{
    A a;
    a.b.id = vec.size() - 1; // Also ugly!
    vec.push_back(a);
}

【问题讨论】:

  • 如果B 只用作A 的成员,我只会使用参考。
  • @super 参考哪里和什么?对向量成员的引用会导致错误,因为向量调整大小会增加其在堆内存空间中的大小。
  • a.b.id = vec.size() - 1; // Also ugly! 可能是错误的。考虑size() 为零的空情况。
  • @user4581301 好点。但这是出于演示目的。不是主要问题。
  • 你很少需要全局变量。如果我们对这些类有更多了解,就更容易提出改进建议。

标签: c++ class oop vector struct


【解决方案1】:

首先,您根本不应该使用全局变量。这是一种非常糟糕的做法,因为任何缺少访问规范的变量都可以在任何时候被程序更改。

对于像这样的小程序来说,这不是什么大问题,但在更大的项目中,如果您继续使用全局变量,您最终可能会遇到一些非常讨厌的错误。

接下来,重新定义这个结构是有意义的。没有明确的规则,但在我看来,结构不应真正包含数据成员以外的任何内容。相反,最好定义一个类,如果你想要的话,可能包含一个类似于 struct b 的结构。然而,就我个人而言,这不是我解决这个问题的方式。

考虑改为定义一个类 A,您可能有一个“值”变量。然后,您可以定义一个函数,该函数传递一个您想要分配的值,该值将一个值分配给该类的“值”变量。

然后在 main 中,您可以实例化一个“A”向量,然后设置一个 for 循环(或其他类型的循环,毕竟这是您的选择)。无论你告诉它多少次,那个 for 循环都可以迭代。每次迭代,您都可以实例化一个“A”对象,初始化对象中的值,然后将该对象推到“A”向量的后面。

在主函数范围内的任何点,您都可以通过另一个for循环遍历“A”的向量,以通过索引访问所需的“A”对象,也可以通过该对象访问值.只要您的 for 循环设置为从计数 0 开始迭代,“A”向量的每个元素的索引值将与每次迭代时 for 循环的控制变量相同。

概述的方法不是最佳解决方案,但是与所有编程一样,您的问题有许多解决方案,您可以自行决定哪种方法最好。鉴于所提供的上下文,不要因为信息过多而进一步混淆您是有道理的,但是有很多方法可以改进上述潜在的解决方案。

希望这个答案向您展示了通往同一目的地的另一条路径,这可能更清洁、更易于管理。此外,作为第一次响应者,我希望我自己没有犯任何错误(如果我在这里搞砸了其他读者,请告诉我)!祝你编程好运!

【讨论】:

    【解决方案2】:

    我认为您需要将封闭类的指针传递给嵌套类才能使用封闭类的非静态成员。

    请参见此处的 PIMPL 习语: Why would one use nested classes in C++?

    可以这样写类:

    #include <iostream>
    #include <memory>
    
    struct A
    {
        int val;
        int getv() {return val;}
        struct B
        {
            A * my_parent;
            B(A * a) : my_parent(a) {}
            void func()
            {
                std::cout << my_parent->val << std::endl;
            }
        };
        std::unique_ptr<B> b;
        A();
    };
    
    A::A() : b(new B(this)) {}
    
    int main()
    {
        A a;
        a.val = 1;
        a.b->func();
    }
    

    【讨论】:

    • 我认为这行不通。因为我在向量中使用 A;它使用堆内存空间并调整大小(更改引用)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2011-10-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多