【问题标题】:How Can I Redefine a Classs Outside of A Loop?如何在循环之外重新定义类?
【发布时间】:2021-03-12 07:36:49
【问题描述】:

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

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;
}

那么有什么区别呢?以及如何删除和重新定义具有相同名称的类。我不想找到不同的名字。我将在循环之外使用它并在向量中推回它们。

其实我想做的是:

#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;
}

【问题讨论】:

  • 您重新声明 A 两次,而只是分配新值。 MyClass * A = new MyClass();delete A;A = new MyClass();
  • delete(A);你有Python背景吗?
  • @fvalasiad 这次它给出了错误:'A': redefinition;多次初始化
  • @Ayxan Haqverdili 不,我没有。
  • 注意:在您包含任何 std 头文件之前,using namespace std; 毫无意义。您可能还想看看Why is using namespace std; considered bad practice?

标签: c++ class redefinition


【解决方案1】:

嗯,这里

    MyClass A;
    MyClass A;

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

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

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

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

在 for 循环的最后一种情况下(可以是任何块作用域,与对象创建/销毁有关),您正在创建一个堆栈分配的对象,该对象内部仅包含原始类型,然后每个循环都被创建和销毁使用编译器提供的默认 ctor/dtor。

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

从 cmets 编辑: delete 将删除您要删除的指针所指向的数据。 如果你想一个接一个地定义相同的变量,你应该以这种方式在块作用域中定义第一个变量

 {
     MyClass* A;
 }
 MyClass* A;

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

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

【讨论】:

  • 感谢您的回答。也许我应该问我怎样才能摆脱一个初始化的类。显然删除是不够的。
  • 我更新了我的答案以更好地回答您的疑问(这不适合评论)
【解决方案2】:

在这里您尝试创建两个具有相同名称的对象:

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;
}

有没有办法从记忆中清除它们?

您在更新后的问题中在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
}

【讨论】:

  • 感谢您的回答。在 MyClass A 使用它的方法产生值和 v_A.push_back(A); 之后我想做什么.我用不同的方式手动重复这个循环。我不想使用 MyClass A2 和 MyClass A3 并继续使用 A30。我认为有一种方法可以轻松清除“A”中的内存。
  • @KC_ 不客气。我没有看到您正在谈论的代码,但我假设您有一个 std::vector&lt;MyClass&gt;?在这种情况下,您甚至不需要命名对象。您可以将emplace_back(...MyClass constructor arguments...) 放入向量中。如果您知道要填充什么,您还可以一次性使用所有对象初始化 vector
  • 是的。它是这样的:vector v_A;我的A类; // 多行; v_A.push_back(A);: MyClass A2; // 许多不同的行; v_A.push_back(A2):;继续。有没有办法不使用A A2 ... A30。我不想保留它们。我已经有了他们的向量。
  • @KC_ this 你可以使用吗?
  • @KC_ 很好。无需抱歉 :-) 如果我没有完全回答您的问题,您可以update your question 并提供更多详细信息,我会尽力解决您添加的问题。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-09
    • 2018-06-08
    • 1970-01-01
    • 1970-01-01
    • 2012-05-20
    • 2015-09-05
    • 2010-11-18
    • 2020-11-20
    相关资源
    最近更新 更多