Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
enter image description here
As you can see, the destructor complains "Use of undeclared identifier 'a'
Is my array out of scope? How can i delete it, when i call the destructor?
a has to be a member variable of the class. As you have it now its a local
a needs to be a data member of hashtable in order for this to work. Right now it is a variable local to the constructor, and the memory allocation is therefore leaked when the constructor terminates.
However, even if you correct this problem, beware the rule of five: if you implement any of the following you need to implement or delete all of them:
Destructor
Copy constructor
Copy-assignment operator
Move constructor
Move-assignment operator
If you do not, the compiler will generate them for you and it will get them wrong in this case. Simply copying the pointer value to the new object is not enough; a new allocation needs to be made and the contents copied (except in the case of a move). The compiler-generated versions will result in a use-after-free or double-delete.
You can avoid all of this by using std::vector<int> instead of trying to manage your own memory.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 months ago.
Improve this question
The syntax of the destructor is ~classname. This results in the need to explicitly write the type of object in the destructor call. To avoid this, C++17 introduced std::destroy_at.
So, what was Bjarne Stroustrup's original rationale for choosing the ~classname syntax for the destructor? If the syntax does not depend on the types, std::destroy_at is not needed.
First of all, I am not sure about the initial rationale for ~ in ~T(). The thing is that most of the time it does not matter how the destructor is called manually.
Usually you never call a destructor explicitly. Most of your variables should use automatic storage:
{
foo x;
}
The destructor of x is called automatically when x goes out of scope. Explicitly calling the destructor of x is wrong, because once it goes out of scope it would be called again resulting in undefined behavior.
Sometimes you need dynamic allocation (do it via smart pointers, but for the point here manual is "ok"):
foo* p = new foo();
delete p;
You must delete what you created via new. Also here calling the destructor explicitly would be wrong, because delete calls the destructor and frees the allocated memory. Only calling the destructor will not free the memory and calling the destructor twice is undefined behavior.
The only case you have to call a destructor explicitly is when you allocate memory and create the object in two seperate steps via placement new: What uses are there for "placement new"?.
Placement new isn't something you use everyday. It is mainly found in libraries. It is a case where you need to call a destructor explicitly and that is the case when std::destroy_at can be handy.
Suppose you write this code:
void foo() {
auto x = returns_some_pointer();
// ....
... now delete *x ...
}
Suppose returns_some_pointer returns a pointer to some object. Further suppose that object has been created via placement new and at the end of foo we want to call its destructor. foo doesn't need to know the type of x for anything. To call the destructor it would need to know T to be able to call ~T(). The type can be deduced from x itself, but thats not very convenient. A very convenient way to deduce T is to use a function template, and that is destroy_at(x);.
TL;DR: For most cases it does not really matter how the destructor is called, because it will be either called automatically or under the hood by calling delete. std::destroy_at is not a replacement for the destructor, but rather a convenience method to deduce the type of the object whose destructor is to be called.
Constructors and destructors were a part of C++ from the very earliest days. (They predated the name "C++.") They predated templates as well as the standard container types like vector that templates made possible. In those early days there was little or no allowance for manual construction/destruction as a separate operation from new and delete (e.g. there was no placement-new). Nested classes were also not supported.
All in all, there was no question of ever needing to refer to the destructor except as part of its definition, and no question that there would be any doubt or complexity in forming the destructor's identifier.
Naming the constructor after the class fits with C's general tendency for declarations to resemble the usage of the things they declare (e.g. int *a(int b) results in something where *a(b) is well-formed). The destructor is conceptually linked to the constructor, so it would be weird for the class name to show up in the constructor but not the destructor. And with no support for operator overloading (at the time) beyond operator=, there was no question of confusing ~classname with an overloaded operator~. So it was a simple, low-stakes, mildly witty syntax detail.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Suppose we declare A to be of type Type:
Type A;
Question: is the Type constructor for A called at this point? Or is it only after we initialize A that a constructor is called?
is the Type constructor for A called at this point? Or is it only after we initialize A that a constructor is called?
You are initializing A here, whether you explicitly provided a value for that process or not.
There is no opportunity to initialise A "later"; you can only assign to it later. (Early C texts talk about "initialising" numeric values long after declaration, but that's a different language, a different century, and a different set of descriptive idioms.)
So, yes, the constructor is called as soon as the object's lifetime begins. That's either right there and then, on that line, or if a class member then of course it's when the encapsulating class is being initialised and it's this member's turn.
Of course you could have proven this with a simple std::cout pair.
Yes, it is called immediately. When you assign it a value, the assignment operator is called instead.
The only exception is this:
Type a = value;
Here some compiler with some settings may relax it and call constructor directly with the value as parameter. But it still needs to be part of declaration.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
I am fairly new to the language, and I can't seem to find a good explanation on constructors.
When I don't create a constructor, according to many resources, a default constructor is created, which doesn't do anything. However, is there something that the constructor does behind the scenes that instantiates an object?
A comparison between the default constructor and my own defined constructors would help me understand this.
Thanks a ton in advance!
~novice
The constructor initializes the variables(fields) of a class. The default constructor initializes to default values. Example, string to "", integers to zero, doubles to 0.0, boolean to false an so on. When you create a constructor you're customizing the variables initialization.
A constructor is essentially the conditions called upon the object being created. If you want to input an int, for example, into the initialization of the object, you would create a constructor that takes "int x" in the parentheses, which is then referenced within the constructor statements.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
C++ will create copy constructor and copy assignment operator for class. My questions is why it is creating two member function ? What is the significance and what is the difference by copying the object by copy constructor and copy assignment operator? Thank you in advance.
Copy assignment and copy construction do different things. Copy assignment has to take a fully constructed object and change it, while copy construction has to take a non-fully constructed object and do that initial construction.
For example copy assignment on a class that manages a resource has to ensure that its old resource is properly disposed of after it has taken ownership of the 'copied' resource, whereas the copy constructor doesn't have any previous resource to deal with.
If you have pointers as data members in your class, and if they are directly getting copied to another object, more than one object will access that pointer memory (unintentionally). To avoid that we can override copy constructor/assignment operator.
If you do not override these two functions, compiler copies bit by bit to another object.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I've noticed this weird behaviour/bug where a class method is called before the actual object is initialized. I have a wrapper object, which has operator->() method. Now, when I'm passing the object to another object as constructor parameter in a constructor using the operator->() method, the actual wrapper object doesn't get constructed, but rather just runs the operator->() method.
As the actual code sample is pretty complicated and depends on many other things, I'll just show C++ code snippet which may not compile properly:
template<typename T>
class wrapper_object_type
{
public:
wrapper_object_type() {/*does not run*/}
T* operator->() {/*does run*/}
};
class bad_behaviour
{
public:
bad_behaviour() : another_object(wrapper_object->t_object)
{/*crashes(0xccc access violation*/}
};
So is there something defined in the standard that may allow such behaviour? Or more accurately, are there some implicit constructions etc. which could bypass the default construction?
Probably you use wrapper_object before it gets initialized. Member variables are constructed in the same order in which they are declared in the class, so make sure wrapper_object is declared before another_object.
(Assuming wrapper_object and another_object are members variables of bad_behaviour, but without a more reasonable code sample it's hard to say.)
Well I did it the hardway; I switched the objects from stack to heap and initialized them explicitly via new keyword rather than in initializer list. As I thought, that didn't reproduce the weird behaviour, so it worked as intended. What I'm thinking now, is that it may be actually a compiler bug, since the way I did it via initializer list is analog to how I fixed the problem. Only thing that changed was the fact that I didn't allocate them in heap before.
I also tried to provide working code which reproduces the bug, but the bug wasn't shown there. It may be because the actual code where the bug was noticed, relies quite heavily to template types and wrapper objects. As it works now when the objects are allocated in heap, the bug isn't in the code but rather in the compiler.