With regards to this piece of code:
#include <iostream>
class CClass1
{
public:
void print() {
std::cout << "This should print first" << std::endl;
}
};
class CClass2
{
public:
void print() {
std::cout << "This should print second" << std::endl;
}
};
So someone asked an interesting question about having a "free pointer" (so to speak) which can point to multiple instances of different objects without having to create a new type of that object. The person had the idea that this pointer can be of type void * and since it is void, it can be made to point to any instance of an object and access the object's public properties.
The following solution was submitted:
int main() {
void *pClass(NULL);
((CClass1 *)(pClass))->print();
((CClass2 *)(pClass))->print();
std::cin.ignore();
return 0;
}
My question is why does the above work, but this doesn't:
int main() {
(CClass1 *FG)->print();
(CClass2 *FG)->print();
std::cin.ignore();
return 0;
}
Your first example exhibits undefined behavior, by calling a non-static member function via a pointer that doesn't point to a valid object. It only appears to work by accident, because the function in question just happens not to use this in any way.
Your second example is, quite simply, syntactically incorrect. I'm not even sure what you are trying to do there; the code makes no sense.
Related
I am learning c++ from 'Teach yourself c++ in 21 days' by Liberty and Jones. Compiler I am using is gcc 6.3.0. I am on pointer topic. First I am writing one code similar to the one book gives which works fine. Here it is:
#include <iostream>
using namespace std;
class Cat
{
public:
Cat();
int Getage() {return *itsage;}
private:
int *itsage;
};
Cat::Cat()
{
itsage=new int;
*itsage=2;
}
int main()
{
Cat *Mani=new Cat;
cout << "Mani is a cat whose age is: " << Mani->Getage();
cout << endl;
return 0;
}
Output: Mani is a cat whose age is: 2
Now instead of using constructor, I thought of using accessor function to set age. I wrote the following code which gave me output as above but I have doubt why this code work. Here is the code I wrote.
#include <iostream>
using namespace std;
class Cat
{
public:
void Setage(int age) {*itsage=age;}
int Getage() {return *itsage;}
private:
int *itsage;
};
int main()
{
Cat *Mani=new Cat;
Mani->Setage(2);
cout << "Mani is a cat whose age is: " << Mani->Getage();
cout << endl;
return 0;
}
Doubt: What I studied so far tells me that whenever pointer declared, it should get initialized, i.e. we should assign some memory address to it. In the first code, we are initializing our pointer member variable in the constructor by this command itsage=new int; which looks fine. But in the second code, I nowhere assigned any memory address to pointer itsage. But still code worked fine. I am little confused here.
I have one more doubt(I am asking here itself as it is related to the above code. If it's bad, I will ask it in different question.) I thought of making pointer itsage in the above code public. But I don't know how can I access it. I tried the following but didn't work.
#include <iostream>
using namespace std;
class Cat
{
public:
int *itsage;
};
int main()
{
Cat *Mani=new Cat;
Mani->*itsage=2;
cout << "Frisky's age is " << Mani->*itsage;
return 0;
}
So how to access public pointer member variable of object created on heap?
Thanks.
About your first question. I was confused at first, this is a neat answer, which shows that the compiler did it for you.
About your second question, it's nothing but an improper way of accessing the pointer. You should realize that when trying to access the content of a pointer, you must get its address then go to its content. So you need to:
Get its address: Mani -> itsage
Access its content: *(Mani -> itsage)
In this function:
void Setage(int age) { *itsage=age; }
you are dereferencing itsage, but it's not pointing to valid memory. This invokes undefined behavior. You need to do:
void Setage(int age) {
itsage = new int;
*itsage=age;
}
For the second question, the correct syntax to access a member variable of pointer type is:
*(Mani->itsage) = 2;
Note that this is undefined behavior too, for the same reason as above. The fix is also the same; you need to do:
Mani->itsage = new int;
*(Mani->itsage) = 2;
But in the second code, I nowhere assigned any memory address to pointer itsage. But still code worked fine. I am little confused here.
That's a fair doubt. In fact, your 2nd code should never work, as no memory had ever been allocated to itsage. If it still somehow "worked" for you then it is still a typical undefined behaviour.
You should still allocate the memory before usage as usual, and free it in the constructor. As your class doesn't even have a destructor, perhaps you should choose unique_ptr instead:
class Cat
{
public:
void Setage(int age) { itsage = make_unique<int>(age); }
int Getage() { return *itsage; }
private:
unique_ptr<int> itsage;
};
I'm having trouble understanding why this code works. I've been in the C# world for awhile and wanted to brush up on C/C++ before diving into the new stuff in C++11 like RValue Refs and move semantics.
I'm wondering why this code that I wrote works:
class InnerMember
{
private:
int _iValue;
public:
InnerMember(): _iValue(0) {};
InnerMember(int iValue) : _iValue (iValue) {};
int GetValue(void) { return _iValue; }
int SetValue(int iValue) { _iValue = iValue; }
};
class TestClass
{
private:
InnerMember _objValue;
public:
TestClass() : _objValue(1) {};
void SetValue(int iValue)
{
_objValue.SetValue(iValue);
}
InnerMember& GetRef(void)
{
return _objValue;
}
virtual ~TestClass() { std::cout << "I've been released!" << std::endl; }
};
int main (int argc, char *argv[])
{
TestClass* pobjTest = new TestClass();
std::cout << "Before:" << std::endl;
std::cout << pobjTest->GetRef().GetValue() << std::endl;
pobjTest->SetValue(5);
InnerMember& robjInner = pobjTest->GetRef();
delete pobjTest;
std::cout << "After:" << std::endl;
std::cout << robjInner.GetValue();
return 0;
}
The output is:
Before:
1
I've been released!
After:
5
Press any key to continue...
I thought that this would cause an error, since I access the referenced object InnerMember from TestClass after TestClass has been destroyed. Is there some sort of return value optimization going on? Or is it really returning a copy instead of passing back the reference?
I used GCC to with no optimizations (-O0) and it still ran without an issue.
I also used the -S switch to generate the assembly but my AMD64 knowledge is rusty and the name mangling didn't help.
That is undefined behaviour, which means even the "correct" behaviour could happen. When you delete something in C++, it is not erased from the memory, so accessing it before something else writes over it will sometimes maybe still work.
robjInner is still a reference to some deleted object in memory.
This would lead to undefined behaviour.
After deletion, the reference robjInner has been left dangling. You get back the previous value because no one else claimed that piece of memory yet.
Copied from here
A previously-valid reference only becomes invalid in two cases:
If it refers to an object with automatic allocation which goes out of scope,
If it refers to an object inside a block of dynamic memory which has been freed.
The first is easy to detect automatically if the reference has static scoping, but is still a problem if the reference is a member of a dynamically allocated object; the second is more difficult to assure. These are the only concern with references, and are suitably addressed by a reasonable allocation policy.
You can add a print statement inside InnerMember destructor to see what is going on. You will see InnerMember is destroyed after TestClass and the 5 you get is because no one write to that part of memory yet. But that reference is not valid anymore.
I got some weird problem. I use delete operator inside of class method and I want to know how solve this problem.
This is code:
#include <iostream>
using namespace std;
class A
{
public:
int a;
~A() {
cout << "call ~A()" << endl;
}
void action()
{
/* code here */
delete this; //this line depends on some if statements
/* code here */
}
void test2() {
cout << "call test2()" << a << endl;
}
void test() {
a = 10;
cout << "call test()" << endl;
action();
//how can I check if data is deleted?
test2();
}
};
int main()
{
A* a = new A();
a->test();
}
How can I check if data is deleted by delete operator?
Is it even possible?
Using delete this; is nearly always "bad". There are exceptions, but those are really unusual. Think about what you are trying to do. Most of the time, this means that you should have a wrapper object and an inner object that is created/deleted by the wrapper object.
You can't check if something has been deleted (in a reliable way/portable way). In your particular test-case, you are exercising "undefined behaviour" by "using an object after it has been destroyed", which means you can't really tell what is going to happen. You have to trust the C++ runtime that delete does what it says on the label.
In C++ there are other return values available than void. Therefore your action can return something that indicates if this has been deleted or not.
Note that you should not access any non-static data members or call any non-static member functions after deleteing this. Some people feel it to be difficult to guarantee so they ban delete this altogether.
Note to opponents that C++ FAQ claims that delete this is legal construct and I haven't also found anything forbidding it.
I have an object with a method that needs to mutate an outside instantiated object. I've been trying to reference the object in the parameter and that is clearly not working. This is what I have:
#include <iostream>
#include <cstdlib>
#include "Character.h"
using namespace std;
class TesterClass {
public:
void printStuff();
TesterClass(Character& userChar);
private:
Character& character;
};
TesterClass::TesterClass(Character& userChar)
{
character = userChar;
}
int main() {
Character userCharacter;
TesterClass tester(userCharacter);
return 0;
}
My question is how to can I use the instantiated tester class to edit the Character object via parameter passing. I'm very new at C++ and I've read every perceivable definition of reference and point passing, and it just doesn't seem to want to click.
Your constructor should be:
TesterClass::TesterClass(Character& userChar):character(userChar){}
Also see this question.
To address the comment, here's example code where the value is modified:
#include <iostream>
#include <cstdlib>
typedef char Character;
using namespace std;
class TesterClass {
public:
void printStuff();
TesterClass(Character& userChar);
private:
Character& character;
};
TesterClass::TesterClass(Character& userChar):character(userChar)
{
}
void TesterClass::printStuff() {
cout << character << endl;
cout << ++character << endl;
}
int main() {
Character userCharacter = 'a';
TesterClass tester(userCharacter);
tester.printStuff();
cout << userCharacter << endl;
++userCharacter;
cout << userCharacter << endl;
tester.printStuff();
return 0;
}
The output is
a
b
b
c
c
d
I agree with the previous answer/comments - You really should use an initialization list in your constructor. The thing is that your data-members are initialized through the initialization list (this happens BEFORE the body of the constructor is called). In your case, you have a Character& as a member. Since this is a reference, it HAS to be assigned something. I'm not sure which compiler you're using, but AFAIK that code shouldn't even compile.
What you're probably looking for is passing the reference in your main-method, like:
int main()
{
Character userCharacter;
// Notice the use of the &-operator
TesterClass tester(&userCharacter);
return 0;
}
At this point, you're no longer talking about a Character-instance, but of the memory address of the instance. So, since you're passing the mem-address, it's actually a pointer you need in your class, not a reference. (For instance, userCharacter.SomeMethod() is synonymous to (&userCharacter)->SomeMethod() where & references and -> dereferences).
Instead, you could write your TesterClass as:
class TesterClass
{
public:
void printStuff();
TesterClass(Character* userChar);
private:
Character* character;
};
TesterClass::TesterClass(Character* userChar)
: character(userChar) // <- Notice the init-list
{}
That way, in your TesterClass instance, you'll have a pointer that points to the same memory address where the userChar-instance resides.
As a sidenote: It can be good to notice though that userCharacter is a local variable, which means that it'll be destroyed when it runs out of scope. In this case it's not really a problem since tester is local as well. But if you're not used to working with pointers - Just a word of caution. Make sure you never pass the pointer (since you're storing the address in a class member) to a TesterClass-object that lives beyond the scope of the variable whose reference you're passing. That'll leave you with a dangling pointer.
I hope that helps you :)
Here is a sample piece of code. Note that B is a subclass of A and both provide a unique print routine. Also notice in main that both bind calls are to &A::print, though in the latter case a reference to B is passed.
#include <iostream>
#include <tr1/functional>
struct A
{
virtual void print()
{
std::cerr << "A" << std::endl;
}
};
struct B : public A
{
virtual void print()
{
std::cerr << "B" << std::endl;
}
};
int main (int argc, char * const argv[])
{
typedef std::tr1::function<void ()> proc_t;
A a;
B b;
proc_t a_print = std::tr1::bind(&A::print, std::tr1::ref(a));
proc_t b_print = std::tr1::bind(&A::print, std::tr1::ref(b));
a_print();
b_print();
return 0;
}
Here is the output I see compiling with GCC 4.2:
A
B
I would consider this correct behavior, but I am at a loss to explain how it is working properly given that the std::tr1::functions were bound to &A::print in both cases. Can someone please enlighten me?
EDIT: Thanks for the answers. I am familiar with inheritance and polymorphic types. What I am interested in is what does &A::print mean? Is it an offset into a vtable, and that vtable changes based on the referred object (in this case, a or b?) From a more nuts-and-bolts perspective, how does this code behave correctly?
This works in the same manner as it would have worked with plain member function pointers. The following produces the same output:
int main ()
{
A a;
B b;
typedef void (A::*fp)();
fp p = &A::print;
(a.*p)(); // prints A
(b.*p)(); // prints B
}
It would have been surprising if boost/tr1/std::function did anything different since they presumably store these pointers to member functions under the hood. Oh, and of course no mention of these pointers is complete without a link to the Fast Delegates article.
Because print() is declared virtual, A is a polymorphic class. By binding to the print function pointer, you will be calling through an A pointer, much in the same way as:
A* ab = &b;
ab->print();
In the ->print call above, you would expect polymorphic behavior. Same it true in your code as well. And this is a Good Thing, if you ask me. At least, most of the time. :)