如何在循环外重新定义类?

How Can I Redefine a Classs Outside of A Loop?

我正在为以下代码重新定义 class 错误。但是如果我把这个定义放在一个循环中就没有错误。有什么区别?

using namespace std;

#include <iostream>

using namespace std;

struct MyClass
{
    int x;
};


int main()
{
    MyClass A;
    MyClass A;
    return 0;
}

我试过了,但仍然有同样的重定义错误:

#include <iostream>

using namespace std;

struct MyClass
{
    int x;
};


int main()
{
    MyClass* A;
    delete(A);
    MyClass* A;
    delete(A);
    return 0;
}

但是,如果我把它放在一个循环中就没问题

using namespace std;

struct MyClass
{
    int x;
};


int main()
{
    for (int i = 0; i < 5; i++) {
        MyClass A;
    }
    return 0;
}

那么有什么区别呢?以及如何删除和重新定义同名的 class。我不想找到不同的名字。我将在循环外使用它,push_back 在向量中使用它。

其实我想做的是:

#include <iostream>
#include <vector>

using namespace std;

struct MyClass
{
    int x;
    // other variables vectors etc.
};


vector <MyClass> v_A;

int main()
{
    MyClass A;
    // Use A's methods and give values to its variables and vectors.
    v_A.push_back(A);

    MyClass A2;
    // Use A's DIFFERENT methods and give values to its variables and vectors.
    v_A.push_back(A2);

    MyClass A3;
    // Use A's AGAIN DIFFERENT methods and give values to its variables and vectors.
    v_A.push_back(A3);

    // Goes on. I don't want to create different objects A A2 A3 ... A30. I don't want to keep them in the memory.
    // I don't want to write 2 3 ... 30
    // Is there a way to get rid of them from memory?

    return 0;
}

更新代码以包含取决于 linsock 答案的解决方案:

#include <iostream>
#include <vector>

using namespace std;

struct MyClass
{
    int x;
    // other variables vectors etc.
};


vector <MyClass> v_A;

int main()
{
    {
        MyClass A;
        // Use A's methods and give values to its variables and vectors.
        v_A.push_back(A);
    }

    {
        MyClass A;
        // Use A's DIFFERENT methods and give values to its variables and vectors.
        v_A.push_back(A);
    }

    {
        MyClass A;
        // Use A's AGAIN DIFFERENT methods and give values to its variables and vectors.
        v_A.push_back(A);
    }

    // Goes on. I dont want to create different classes A A2 A3 ... A30. I dont want to keep them in the memory.
    // I dont want to write 2 3 ... 30
    // Is there a way to get rid of them from memeory?

    return 0;
}

您在此处尝试创建两个同名对象:

int main()
{
    MyClass A;
    MyClass A;
    return 0;
}

如果这有效,您将无法区分这两个对象。例如,A.x = 10; 会在哪个 A 上工作?编译器不知道所以它拒绝编译。

这里你在每个循环中创建一个新的 MyClass 对象,它在结束时被销毁 }:

for (int i = 0; i < 5; i++) {
    MyClass A;
    A.x = 10; // totally fine - there is only one `A` at a time
} // the A is destroyed here

您尝试使用指针的部分应该像这样才能工作:

int main() {
    MyClass* A = new MyClass;
    A->x = 10;                // example
    delete A;

    A = new MyClass;          // not "MyClass* A = ". A already exists
    A->x = 20;                // example
    delete A;
}

Is there a way to get rid of them from memory?

您在更新问题的 vector 中得到的是 。您创建的自动实例在作用域结束时被销毁。

在您编辑的问题中,您甚至不需要任何命名的 MyClass 对象:

#include <iostream>
#include <vector>

struct MyClass {
    int x;

    void foo() { std::cout << x << '\n'; }
    void bar() { std::cout << x*2 << '\n'; }
    void baz() { std::cout << x*3 << '\n'; }
};

std::vector <MyClass> v_A;

int main() {
    v_A.emplace_back(1);
    v_A.back().foo();    // calls foo() on the last element in the vector

    v_A.emplace_back(2);
    v_A.back().bar();    // calls a different method on the new object

    v_A.emplace_back(3);
    v_A.back().baz();    // calls a different method on the last object
}

在第一个示例中,您在同一 scope 中创建了 2 个类型为 MyClass 且名称相同的变量,因此您显然遇到了重定义错误。在第二个例子中,同样的情况只是现在变量是指向 MyClass 的指针,删除它们只会释放它们指向的内存,但指针仍然存在。 最后,在 for 循环示例中,您在循环的每次迭代中不断创建和销毁“MyClass”变量,因此在同一范围内永远不会存在同名变量。

嗯,这里

    MyClass A;
    MyClass A;

你定义了同一个 class 变量两次(顺便说一句,你的编译器应该用编译失败的消息来突出显示)

和你在这里做的一样,但更糟

 MyClass* A;
 delete(A);
 MyClass* A;
 delete(A);

因为您还试图删除您定义但从未初始化为指向有效内存区域的指针。

在 for 循环的最后一个例子中(可以是关注对象 creation/destruction 的任何块作用域),你正在创建一个堆栈分配对象,它内部只包含基本类型,然后每次循环它使用编译器提供的默认 ctor/dtor 创建和销毁。

我建议你找一个好的教程来更好地理解你应该如何在 C++ 中处理这种行为。

根据评论编辑: delete 将删除您要删除的指针指向的数据。 如果你想一个接一个地定义相同的变量,你应该以这种方式在块范围的部分中定义第一个

 {
     MyClass* A;
 }
 MyClass* A;

这样内部定义的MyClass* A退出作用域后会丢失,可以在外部作用域中定义

即使这实际上是可能的,我还是建议您不要这样做以提高代码的可读性。