error: 'new' cannot appear in a constant-expression - c++

class A
{
int data;
public:
void display()
{
cout<<"Value is "<<data;
}
void set_data(int x)
{
this->data = x;
}
A object = new A();
};
When I run the above code, I get the error stating "new cannot appear in constant expression". Why is it so?

Operator new returns a pointer but A is not a pointer type. You want A*:
A* object = new A();
You also want to move the above statement outside your class body and place it into appropriate function such as main():
int main() {
A* p = new A();
// do work
delete p;
}
That being said you either don't need a pointer at all and you can simply use an object with automatic storage duration:
A object;
Or you want to consider using a smart pointer such as std::unique_ptr:
std::unique_ptr<A> p = std::make_unique<A>();

class A
{
public:
A * object = new A(); // In any case not: "A object = new A();"
};
Or:
class A
{
public:
A object;
};
-
See (let's assume, for a moment, that you don't get the error), in both cases, on the first construction of A object, it creates another A object as a data-member. This A data-member (let's call it object.object ) creates in its turn another A as its data-member (let's call it object.object.object), and so to infinity (or until no more memory). I mean, as a data-member, it can't be either as A* object = new A();, or as A object;
-
I am not sure what was your intention, but if you want to link one A-object to another A-object, the class should be something like that:
class A
{
public:
A * object = nullptr
};

you have to make object of class A into main().
void main(){
A object;
}

First of all, you cannot create an object in the class declaration. Class declaration is like a blue print of the class. It is to say these are the components of my class - variables and member functions. You cannot instantiate anything inside it as no memory is allocated during this stage.
Note that you can instantiate an object inside one of the member function including constructor. These are called during object creation when memory is allocated.
Even if you use this statement inside a constructor you will go into an infinite loop as the constructor calls its constructor and so on until you have memory overflow.
You can declare the object in main like this:
int main() {
A obj = new A();
//other operations
} //Object A is destroyed once you come out of main.
Or dynamically like this
int main() {
A* obj = new A(); //dynamic allocation
//other operations
delete obj; //explicitly destroy
}

Related

What will be happen if you dynamically allocates memory for one object of the class as an argument?

class Example
{
private:
Example* pointer;
Example* pointer2;
public:
Example();
void setPointer2(Example* object);
};
Example::Example()
{
pointer = new Example();
}
void Example::setPointer2(Example* object)
{
this->pointer2 = object;
}
int main()
{
Example object;
object.setPointer2(new Example());
return 0;
}
Delete is not important. I just want to know what is the differences between this two object which is adresses holding by pointer and pointer2. Are they differently allocated? The actual question is, does it matter where to use the "new" operator?
A major problem you have in your code is infinite recursion! The constructor you have defined:
Example::Example()
{
pointer = new Example();
}
creates a new object of its own type. This will call the constructor (again), and that call will call the constructor (again and again...)
But, other than that issue, it doesn't really matter whether you create a new object by directly assigning its address to pointer or if you create the object elsewhere and then assign its address (later) to pointer2. Both will point to an object of the class.

Is the heap-allocated object of a class alive after its scope but before calling its destructor in C++

EDITED: Let's say we don't call explicitely the destructor of a heap-based object (delete A). If the pointer that points to "A" goes out-of-scope, is there a way the dynamic object remain accessible? for e.g., in the following code, can "a" be still alive after if-closing }?
class A{
void itsmethod();
};
int main()
{
if (true){
A* a = new A;
}
//...here how can I use dynamically allocated object?
a->itsmethod();
}
EDIT: As it was responded, the simplest immediate way is defining the pointer outside of if statement, but I am just wondering if there is any other option to prolong lifetime of dynamic object? Accordingly what else "A" class should provide? For instance passing by reference? Or equipping the class with move constructor... These suggestions may be irrelevant, I would like to hear your feedback.
I wonder if the object "a" is still alive after if-closing }?
The object a, which is a pointer, is not alive after the closing } of the if statement. The object to which a points to is in memory but it is not accessible with the posted code.
To be able to access the object to which a points to, declare a before the if statement.
int main()
{
A* a = nullptr;
if (true)
{
a = new A;
}
if ( a != nullptr )
{
a->itsmethod();
}
}
No and Yes: yes because dynamic memory is not freed up automatically. No because the code doesn't compile because a is scoped to if block and you are trying to use it from outside.
class A{
public:
int x;
};
int main(){
A* ptrA = NULL;
if(true){
// Everything declared here is accessible only here whatever being dynamic or static.
ptrA = new A;
ptrA->x = 10;
int x;
}
if(ptrA){
std::cout << ptrA->x << std::endl; // 10
delete ptrA;
}
return 0;
}
You must free up memory always when you're done with it otherwise it is a memory leak.
Above x is declared inside the if block on the stack so when end of if block is reached x will be destructed.
The object created by the new expression (i.e. by new A) will continue to exist.
The pointer a itself, since it has passed out of scope, will cease to exist as far as your program is concerned.
The net effect is that the dynamically allocated object is "leaked". It continues to exist after the block but there is no pointer or reference to it.
If you do something like
int main()
{
A *b;
if (true)
{
A* a = new A;
b = a;
}
a->itsmethod(); // diagnosible error
b->itsmethod(); // will work correctly
delete b; // destroy dynamically allocated object
b->itsmethod(); // undefined behaviour
}
then a->itsmethod() will give a compiler diagnostic (since a no longer exists) but the first b->itsmethod() will use the object created by the new expression. The second b->itsmethod() will compile, but yield undefined behaviour, since it accesses an object that no longer exists (due to the preceding delete b).
This happens because the pointer b continues to exist and, within the enclosed block, is assigned the value from a. So it then contains the result of the new expression.
No. The object 'a' will not be accessible anymore since its scope belongs to the if statement. However, there still is a memory address containing that object. This is why its good to do 'garbage collection' in programming.
Let's consider this demonstrative program
#include <iostream>
struct A
{
const char *s;
std::ostream & operator ()( std::ostream &os = std::cout ) const
{
return os << s;
}
};
int main()
{
A *a1;
if ( true )
{
A *a2 = new A { "Hello, Sepideha" };
a1 = a2;
}
( *a1 )() << std::endl;
delete a1;
return 0;
}
Its output is
Hello, Sepideha
Here the object a1 that has the type A * has the outer-most block scope of the function main.
The object a2 has the block scope of the if statement. It is alive only within this block.
At the same time there is dynamically created unnamed object of the type A pointer to which is assigned to a2 and then to a1. This unnamed object will be alive until the operator delete for a pointer that points to the object will be called. That is its live-time does not depend on the block scope of the if statement.
Because the pointer a1 points to this unnamed object then the pointer can be used outside the if statement to access the unnamed object in the dynamic memory.
After the statement with the delete operator this unnamed object stops to exist. But the object a1 is still alive.

Deleting instantiated objects outside of a function?

How do you delete an instantiated object inside a function then delete when another function is called?
For example:
int function_test(){
object* a = new object();
}
int function_test2(){
delete a;
}
Object a needs to be deleted when function_test2() is called. Function_test() creates and sets the value of object a.
In order to delete something, you need a pointer to something.
When you allocate an object in function function_test and want to delete it in function_test2 you need to take care of a way for function_test2 to get a hold of the pointer to the object you wish to delete.
There are multiple ways of doing that, but the most common one is for function_test to return the pointer to the caller, and then passing that pointer to function_test2:
object* function_test() {
object* a = new object();
...
return a;
}
void function_test2(object* a) {
...
delete a;
}
The caller would need to "transfer" the pointer, like this:
object obj = function_test();
...
function_test2(obj);
Other ways of transferring the pointer are using file-static pointers, using global pointers, and using instance variables when functions function_test and function_test2 are member functions of a class.
You can't transfer local variables between functions. If you like to do something like this, I suggest you return the pointer, so you can pass it to the next function.
object *function_test()
{
auto *o = new object{};
return o;
}
however, this has as disadvantage that you have to capture this variable everywhere where you call it and have to to do memory management. Most likely you just want to use something object oriented, similar to:
class ObjectOwner final
{
public:
int function_test(){
a = new object();
}
int function_test2(){
delete a;
}
private:
object *a{nullptr};
};
which can be used as:
ObjectOwner owner;
owner.function_test();
owner.function_test2();
Even better would be using a std::unique_ptr<object> so that when you forget to call the 2nd function, the memory is freed.
Finally, you can consider using a constructor/destructor.
class ObjectOwner final
{
public:
ObjectOwner()
: a(std::make_unique<object>())
{
}
~ObjectOwner() = default;
void func() { /*Do something with a*/ }
private:
std::unique_ptr<object> a{};
};
Allowing you to write:
ObjectOwner owner{};
owner.func();

Class constructors in C++

I'm a beginner to c++ so there are a lot of things quite not clear in my mind.
I have this code I need to write and in a class I make a constructor.
However, I don't need any parameters because I read from a file-stream inside the constructor. So my questions are:
1.Can I make a constructor like this:
class myClass {
private:
string title;
string organizer;
public:
myClass() {
title = stringRead();
organizer = stringRead();
}
}
where stringRead() is a function I have written to read from my file??
2.How do I call it afterwards when I need it? I know that the default constructror is being called like that:
myClass A;
A = myClass();
Is it the same?
3.If I have a pointer, how do I call the constructor again? This doesn't seem like it should be right...
myClass *B;
B = myClass();
Thanks in advance! =D
1) This constructor will work but you should favor using an initialization list (assuming stringRead() isn't a member function of myClass
class myClass {
private:
string title;
string organizer;
public:
myClass()
: title(stringRead()),
organizer(stringRead())
{ }
};
2) myClass A; is what you should be doing. You could alternatively have auto A = myClass(); which, after optimizations, will be the same thing. Without optimizations a temporary will be constructed, and then A will be move constructed from it, so this won't work with unmovable objects (your object is movable)
3) If you want to use a raw pointer then you would use
myClass *ptr = new myClass;
// bunch of code
delete ptr;
However, you'd be better using a smart pointer to control its lifetime. This way you won't need to manually delete
std::unique_ptr<myClass> ptr(new myClass);
or make_unique in c++14
auto ptr = std::make_unique<myClass>();
And of course use a shared_ptr if you have shared ownership
I think it's OK to assign the value returned by a function to a member of a class.
You can initialize it as you suggested (with myClass A;)
When you use pointers, you need myClass *k=new myClass();. You should remember to delete the object you created with delete k;.
Your constructor is fine, so long as the functions used within it are globals or static functions of this or another class.
myClass A; will invoke the constructor you have written.
To use a pointer, you need B = new myClass(). That will also call the same constructor. Don't forget to delete B at some point else you'll leak memory.
Do bear in mind that if an exception is thrown in a constructor then the destructor is not called.
Yes, you can, but it might not be the best approach. Reading from input can fail, failure in a constructor is often a non-recoverable event you'll want to handle. A good approach is reading the values outside the costructor, handling errors and calling the constructor only when you have "everything ready". Like this:
class myClass {
private:
string _title;
string _organizer;
public:
myClass(const string &title, const string &organizer) {
_title = title;
_organizer = organizer;
}
or, by using a more idiomatic C++ initializer list:
class myClass {
private:
string _title;
string _organizer;
public:
myClass(const string &title, const string &organizer):
_title(title), _organizer(organizer) {}
}
and then, somewhere else:
string title = stringRead();
string organizer = stringRead();
myClass A(title, organizer);
No, in this snippet:
myClass A;
A = myClass();
two different things happen: at line 1 the default constructor is called; at line 2, a temporary object is constructed (again, by calling the default constructor) and then assigned to A using the (rval for C++11) copy operator. This expression:
myClass A;
calls the default constructor. If you have parameters:
myClass A(title, organizer);
Nope, this does not even work. A pointer is not an object, you have to allocate the object. At that point, you can get a pointer to it:
myClass A;
myClass *B = &A;
you could also resort to dynamic allocation:
myClass *B = new myClass;
in this case, either remember to call delete B somewhere else or wrap B in a smart pointer:
std::unique_ptr<myClass> B(new myClass());

Re-assinging an "auto_ptr" and Managing Memory

I've a situation like this:
class MyClass
{
private:
std::auto_ptr<MyOtherClass> obj;
public:
MyClass()
{
obj = auto_ptr<MyOtherClass>(new MyOtherClass());
}
void reassignMyOtherClass()
{
// ... do funny stuff
MyOtherClass new_other_class = new MyOtherClass();
// Here, I want to:
// 1) Delete the pointer object inside 'obj'
// 2) Re-assign the pointer object of 'obj' to 'new_other_class'
// so that 'obj' now manages 'new_other_class' instead of the
// object that just got deleted manually
}
};
Is there a way to achieve this? Will the following code do what I want?
void MyClass::reassignMyOtherClass()
{
// ... still, do more funny stuff (flashback humor :-)
MyOtherClass new_other_class = new MyOtherClass();
obj.reset(new_other_class);
}
Will the memory of new_other_class be de-allocated in the default destructor of MyClass?
Yes it will.
You can use
obj.reset( new MyOtherClass() );
And I'd better use such constructor
MyClass():
obj( new MyOtherClass() )
{
}
From MSDN where describing reset
The member function evaluates the expression delete myptr, but only if the stored pointer value myptr changes as a result of function call. It then replaces the stored pointer with ptr.
It will do what you want.