Reputation: 99
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;
}
Upvotes: 0
Views: 147
Reputation: 117298
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
}
Upvotes: 2
Reputation: 310
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.
Upvotes: 2
Reputation: 27
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.
Upvotes: 0