0

I am getting redefinition of class error for the below code. But if I put this definition in a loop there is no error. What is the difference?

using namespace std;

#include <iostream>

using namespace std;

struct MyClass
{
    int x;
};


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

I tried this but still there is same redefinition error:

#include <iostream>

using namespace std;

struct MyClass
{
    int x;
};


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

However If I put it in a loop no problem at all:

using namespace std;

struct MyClass
{
    int x;
};


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

So what is the difference? And how can I delete and redefine a class with the same name. I don't want to find different names. I will use it outside of a loop and push_back those in a vector.

What I want to do is actually:

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

UPDATING THE CODE TO INCLUDE A SOLUTION DEPENDING ON linsock's ANSWER:

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

KC_
  • 89
  • 11
  • You are re-declaring A two times , instead , just assign the new value. `MyClass * A = new MyClass();` `delete A;` `A = new MyClass();` – fvalasiad Mar 12 '21 at 07:40
  • `delete(A);` Do you have a Python background? – Aykhan Hagverdili Mar 12 '21 at 07:45
  • @ fvalasiad This time it gives the error : 'A': redefinition; multiple initialization – KC_ Mar 12 '21 at 07:47
  • @Ayxan Haqverdili No I don't. – KC_ Mar 12 '21 at 07:48
  • Note: `using namespace std;` before you've included any `std` header files is pointless. You may also want to take a look at [Why is `using namespace std;` considered bad practice?](https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice) – Ted Lyngmo Mar 12 '21 at 07:58

3 Answers3

2

Here you are trying to create two objects with the same name:

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

If that had worked, you would not be able to differentiate between the two objects. Which A would A.x = 10; work on for example? The compiler doesn't know so it refuses to compile.

Here you are creating a new MyClass object in every loop that is destroyed at the closing }:

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

The part where you are trying to use pointers should look like this to work:

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?

What you get in the vector in your updated question are copies. The automatic instances you've created are destroyed at the end of the scope.

In your edited question, you don't even need any named MyClass object:

#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
}
Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • Thank you for your answer. What I want to do after MyClass A use its methods produce values and v_A.push_back(A); . I repeat this by hand out of a loop with different ways. I dont want to use MyClass A2 and MyClass A3 and goes on A30. I thought that there would be a way to clear the memory from "A" easily. – KC_ Mar 12 '21 at 08:00
  • @KC_ You're welcome. I don't see the code you are talking about, but I assume you have a `std::vector`? In that case you don't even need a named object. You can `emplace_back(...MyClass constructor arguments...)` into the vector. You can also initialize the `vector` with all objects in one go if you know what to fill it with. – Ted Lyngmo Mar 12 '21 at 08:03
  • Yes it is. It is something like this: vector v_A; MyClass A; // many lines; v_A.push_back(A);: MyClass A2; // many diffrent lines; v_A.push_back(A2):; goes on. Is there a way not to use A A2 ... A30. I dont want to keep them. I will already have their vector. – KC_ Mar 12 '21 at 08:08
  • @KC_ Is [this](https://gcc.godbolt.org/z/q1P9c9) something you could work with? – Ted Lyngmo Mar 12 '21 at 08:11
  • @KC_ That's perfectly fine. No need to be sorry :-) If I haven't fully answered your question, you can [update your question](https://stackoverflow.com/posts/66595964/edit) and provide more details and I'll try to address what you add. – Ted Lyngmo Mar 12 '21 at 08:16
  • Sorry I misunderstood you comment I think. I will check the web page. Thanks. – KC_ Mar 12 '21 at 08:22
2

Well, here

    MyClass A;
    MyClass A;

you're defining the same class variable twice (which by the way should be highlighted by your compiler with a great compilation failure message)

The same you're doing here, but worse

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

since you're also trying to delete the pointer you defined but never initialized to point to a valid memory area.

In the last case of the for loop (which could be any block scope for what concern object creation/destruction) you're creating a stack allocated object, which internally contains only primitive types, then each cycle it gets created and destroyied with default ctor/dtor provided by the compiler.

I would suggest you to find a good tutorial to better understand how you're supposed to deal with this kind of behaviors in C++ .

EDIT from comments: delete will delete the data pointed-by the pointer you're trying to delete. If you want to define the same variable one after the other you should define the first in a block-scoped section in this way

 {
     MyClass* A;
 }
 MyClass* A;

In this way, the inner-defined MyClass* A will be lost after the exit from the scope and you can define it in the outer scope.

Even if this is actually possible, I would suggest you don't do that to enhance code readability.

linsock
  • 190
  • 1
  • 9
  • Thank you for your answer. May be I should have asked how can I get rid of a class initialized. delete is not enough apparently. – KC_ Mar 12 '21 at 08:17
  • I updated my answer to better answer your doubt (which wouldn't fit well in a comment) – linsock Mar 12 '21 at 08:27
0

In the first example you're creating 2 variables of type MyClass with the same name inside the same scope, so evidently you're getting a redefinition error. In the second example the same occurs only that now the variables are pointers to MyClass, deleting them only frees the memory to which they were pointing at but the pointers still exist. Finally in the for loop example you're constantly creating and destroying a 'MyClass` variable at every iteration of the loop, so no variables with the same name ever exist under the same scope.

Eligum
  • 27
  • 7