Could anyone tell me if the pointer "this" in object of class occupy memory when it was created?
class Temp {
private:
Temp &operator=(const Temp &t) { return *this; }
}
this is the address of the object whose member function is being called, and it doesn't need to be stored anywhere.
It is usually implemented by passing its value as a "hidden" argument to the member functions, so it occupies memory in the same way as any other function argument occupies memory.
The "object-oriented" code
struct A
{
int f() { return this->x; }
int x;
};
int g()
{
A a;
return a.f();
}
will usually be implemented like this "non-object-oriented" code:
struct A
{
int x;
};
int Af(A* self)
{
return self->x;
}
int g()
{
A a;
return Af(&a);
}
No, "this" is already by itself a memory reference and hence it would not occupy more memory than the object already does.
Related
#include <iostream>
class Object {
public:
int x;
Object() { }
Object(int x) {
this->x = x;
}
};
class SomeClass {
public:
Object array[10];
int n;
SomeClass() { n = 0; }
void insert(Object o) {
array[n++] = o;
}
};
int main() {
SomeClass s;
Object test = Object(4);
s.insert(test);
return 0;
}
I have this example where I pre-allocate an array of objects in SomeClass and then in some other method, main in this example, I create another object and add it to the array in SomeClass
One thing I think I should do is to switch from array[10] to an array of pointers so that I only create objects when I really need to.
But my question is what happens to the memory originally allocated for array[0] when I do "array[n++] = o" replacing it by the new object "o"? does it get de-allocated?
No, nothing happens. The object's assignment operator gets invoked, to replace the object.
For this simple class, the assignment operator is the default operator which, more or less, copies each of the object's members, one at a time.
(No need to get into move operators, etc..., just yet)
Class A
{
public:
A();
A(int x , int y);
Private:
int x;
int y;
}
Class B
{
public:
B();
A getApointerobject() const;
Private:
A *APointerObject;
int main()
{
B bObj;
cout << bObj.getApointerobject(); //i overloaded the << so that i can //output B objects but it crushes
}
//Class B implementation (This is where i struggle)
A getApointerobject() const {
return *getApointerobject;
}
In B::getApointerobject() you call it recursively. You should change to
A getApointerobject() const {
return *APointerObject;
}
Is B::APointerObject initialized before you call getApointerobject() method?
In getApointerobject you are trying to return the address of the method getApointerobject itself. I guess you code is not even compiling right now?
I guess you want to return your APointerObject
A B::getApointerobject() const {
return *this->APointerObject;
}
But be advised: Built in types, including simple pointers don't have a default constructor. So, since you don't initialise APointerObject in class Bs constructor, you would use a wild pointer. Which means you program would crash at runtime or worse (undefined behavior)
I have this code:
struct Base {};
struct Derived : public Base {
int somedata;
};
std::unique_ptr<Base> createTemporary() {
return std::make_unique<Derived>(); // This code has been simplified
}
template<typename T>
T& convertValueTo(std::unique_ptr<Base>&& obj) {
return static_cast<T&>(*obj);
}
int main() {
int data = convertValueTo<Derived>(createTemporary()).somedata;
return 0;
}
I designed the convertValueTo templated function to return the asked type of the object and mostly for function calls like
auto some_value = convertValueTo<Something_Else>(createTemporary()).a_member_variable;
Now I'm wondering.. is there a safer way to do this? If someone were to use the returned reference from convertValueTo, the temporary will be destroyed as soon as the line expression ends right?
My goal is:
Allow the use of a temporary and destroy it as soon as possible if the reference is not stored (as above)
Allow a safe reference binding to a valid object in case someone wants to
Convert to a unique_ptr of the required type. Then it is clear who has ownership of the dynamically created object, namely the unique_ptr returned from the conversion function. As soon as you create an lvalue reference to the dynamically created object, there will be the possibility that the reference survives the lifetime of your object.
#include <memory>
struct Base {};
struct Derived : public Base {
int somedata;
};
std::unique_ptr<Base> createTemporary() {
return std::make_unique<Derived>(); // This code has been simplified
}
template<typename T>
std::unique_ptr<T> convertValueTo(std::unique_ptr<Base>&& obj) {
auto ptr = obj.release ();
return std::unique_ptr<T> { static_cast<T*>(ptr) };
}
int main() {
int data = convertValueTo<Derived>(createTemporary())->somedata;
return 0;
}
I was playing with an idea where i can have variables in global scope but not construct them. Note that there IS a placement new being ran. However i'd like to know what is undefined or incorrect about this code
#include <new>
#include <cstdio>
#include <typeinfo>
//#define AlignAs alignas(T)
#define AlignAs
template<class T>struct BlockOf {
AlignAs char t[sizeof(T)];
operator T&() { return reinterpret_cast<T&>(*this); }
~BlockOf(){((T*)&t)->~T(); }
};
struct B{
virtual void v(){}
~B() { printf("B\n"); }
};
struct A: B{
A(){printf("a\n");}
int regularDots;
void v() { printf("A virtual\n"); }
};
BlockOf<A> _a;
A&a=_a;
void init(){
new(&a) A;
}
int main() {
init();
A aa;
a.regularDots=9;
printf("%s %s %d %d\n",
typeid(a).name(),
typeid(aa).name(),
typeid(a).hash_code()==typeid(aa).hash_code(),
sizeof(a) == sizeof(aa)
);
B *b = &a;
b->v();
}
This isn't clear
operator T&() { return *reinterpret_cast<T*>(this); }
Instead use
operator T&() { return reinterpret_cast<T&>(t[0]); }
I think that this is required to point at the first member, but using the array explicitly seems safer to me.
To answer your main question, 3.8p8 contains the restrictions on reusing memory belonging to a variable with static storage duration, and since the original type has a trivial destructor, you should be ok.
If a program ends the lifetime of an object of type T with static (3.7.1), thread (3.7.2), or automatic (3.7.3) storage duration and if T has a non-trivial destructor,
the program must ensure that an object of the original type occupies that same storage location when the implicit destructor call takes place; otherwise the behavior of the program is undefined.
I tried copying a pointer to another by using a method inside the class and the this pointer as follows. I am giving the entire test code so that it is clear what is going on.
class test {
private:
int x;
public:
void setx(int x);
int getx(void);
void copy(test *temp);
};
void test::setx(int x) {
this->x = x;
}
int test::getx(void) {
return this->x;
}
void test::copy(test *temp) {
this = temp;
}
And I access this method from the main as follows:
int main() {
test a;
a.setx(4);
cout << a.getx()<<endl;
test *b = new test;
b->setx(4);
cout << b->getx()<<endl;
test *c;
c=b;
cout << c->getx()<<endl;
test *d;
d->copy(b);
cout << d->getx()<<endl;
}
However it gives the following error
In member function ‘void test::copy(test*)’:
error: lvalue required as left operand of assignment
All the other method involving the this pointer works fine except for the copying part. Am i doing some elementary mistake in using the this pointer?
You cannot overwrite this. The this pointer is a constant, so you're not allowed to change it. And what would that mean anyway? You can't change the object that you're in. You can change the values within that object, but not the object itself.
You need to copy other objects by value (by what is stored in the object), not by pointer.
Also, you shouldn't have a function called copy; that's what copy constructors and copy assignment operators are for.
You cannot modify the this pointer. You can however modify *this:
void test::copy(test *temp)
{
*this = *temp;
}
Also, you should rename the data member or the parameter, so you don't need this->:
class test
{
int m_x;
public:
void setx(int x)
{
m_x = x;
}
what is test::copy supposed to do?
Clearly you cant assign a different address to your current object. So it is invalid.
if this is supposed to initialize the current object with the values of some other object then it should look like this:
void test::copy(test *temp) {
this->x = temp->getX();
}