variables scoping when inheriting - c++

I have two classes in C++, where one inherits from the other:
class A {
public:
virtual void Initialize(){
m_MyString = "Default value";
}
protected:
string m_MyString;
}
class B : public A {
public:
void Initialize(){
A::Initialize();
m_MyString = "New Value";
}
}
Is there a difference between the above class B and this one?
class B : public A {
public:
void Initialize(){
A::Initialize();
A::m_MyString = "New Value";
}
}
It seem using the scoping operator will result in a the string having garbage, correct? I'm thinking when it overrides, the A::m_MyString is different than B::m_MyString. Does this even make sense?
I'm seeing the variable get set in A, then when we return to B, have garbage. This has to do with "hidden" vs. overridden?

Your code is not valid in many ways. It should look like:
class A { // << errors were here
public:
virtual void Initialize(){
m_MyString = "Default value";
}
protected:
string m_MyString;
}; // << lost ;
class B : public A // << errors were here
{
public:
virtual void Initialize(){ // << virtual
A::Initialize(); // has no effect in the end
A::m_MyString = "New Value"; // same as `m_MyString = "New Value";`
}
}; // << lost ;
In the code above there is no difference with m_MyString. Post your actual code with error.
If your code looks like:
class B : public A
{
public:
virtual void Initialize(){
// here is a difference
A::m_MyString = "New Value";
m_MyString = "New Value";
}
protected:
string m_MyString; // !!! overridden
};
Then there is a difference because B has two instances of m_MyString: A::m_MyString and B::m_MyString.

Are you calling Initialize() from the constructor of A?
Calling virtual methods in constructors is not recommended. For example, if A's constructor looked like
A::A() {
Initialize();
}
B's Initialize method would never get called.
Seeing your actual code would help a lot.

There is no difference between those two versions of class B. Is that the real code that you see garbage in?

The compiler should tell you if you're calling a virtual function from a constructor. But if not, that's definitely a problem.
I think you can make a virtual function final in the derived class, but maybe not. The variable should be the same, regardless of whether or not you explicitly define scope, unless you have a variable of the same name in the derived class.

If this is how your code looks:
using namespace std;
class A
{
public:
virtual void Initialize()
{
m_MyString = "Default value";
}
protected:
string m_MyString;
};
class B : public A
{
public:
void Initialize()
{
A::Initialize();
m_MyString = "New Value";
}
void display()
{
cout<<m_MyString<<endl;
}
};
int main()
{
B b;
A a;
b.Initialize();
b.display();
return 0;
}
Then there is no difference between the two versions of the class B that you described in your question. I added the display function just to make the values clear. By the definitions of the class that you have given, the m_MyString is not being overridden. So the m_MyString variable will have "New Value" assigned to it, i.e. both the classes A and B will share the variable m_MyString.
If you override the m_MyString in class B like
class B : public A
{
public:
void Initialize()
{
A::Initialize();
m_MyString = "New Value";
}
void display()
{
cout<<m_MyString<<endl;
}
protected:
string m_MyString;
};
Then the value of B::m_MyString will contain "New Value" and the Value of A::m_MyString will contain "Default value".

It seem using the scoping operator will result in a the string having garbage, correct?
No, this should work and m_MyString will have "New Value" after b.Initialize() is called.
I'm thinking when it overrides, the A::m_MyString is different than B::m_MyString. Does
this even make sense?
No, when a class B inherits another class A, the object of class B will have a union of the data members of the two. In this case, there is only one m_MyString that is A::m_MyString.
I'm seeing the variable get set in A, then when we return to B, have garbage.
This has to do with "hidden" vs. overridden?
No, there is only one instance of m_MyString.
You definitely need to read this - http://www.openrce.org/articles/files/jangrayhood.pdf.

Related

Access function from another class without having any relations

I'm still new to C++ and I'm trying to know if it is possible to access a function from another class knowing that no one is the father class here . This is a piece of my program to show you what I want to do exactly .
class CSubject
{
public:
CSubject() = default;
CSubject(std::string m_Name){this->Name = m_Name;}
void print(){ std::cout << Name;}
~CSubject(){}
private:
std::string Name;
};
class CStudent
{
public:
CStudent() = default;
void Method2()
{
//Call the print method and print the name "test"
}
~CStudent(){}
private:
};
int main()
{
CSubject AE("test");
CStudent ST;
ST.Method2(); //Print test;
return 0;
}
Forget about classes for a second. You want to call Method2(), and from there, print information that was put into the AE. Suppose you didn't have two classes of your own, but rather, say:
void Method2();
int main() {
const char* AE = "Test";
// ...
Method2();
}
That wouldn't work, right? And it shouldn't work, because local variables in a function (like main()) are usable only within that function's body; that's their local scope. For Method2() to use AE in any way, you have to let Method2() "know" about it. It's the same with classes.
You could use static method and attributes, which can be altered by creating an instance and overwriting it and also getting them from unrelated processes.
I would edit your CSubject class like this:
class CSubject {
public:
CSubject() = default;
CSubject(std::string m_Name) {
CSubject::Name = m_Name;
}
static void print() {
if (CSubject::Name.empty()) //checking is a good practice
std::cout << "The name is empty...\n";
else
std::cout << Name;
}
~CSubject() {}
private:
static std::string Name;
};
And you could access the print method from your Method2 like this:
void Method2() {
CSubject::print();
}
But beware! The static attribute is the only one for the class. If you plan on creating multiple CSubject instances and their new names, then you could store the m_Name attribute as non-static private, print() as non-static public, and Method2 should have a parameter where you pass the CSubject (the whole object or just the data that you need) that is in your interest.

C++ new operator with valid vtable without calling constructor

Is it possible to create an instance of a class on a heap without calling default constructor and with a valid vtable for inheritance? Let me demonstrate what I will like to do:
class A
{
protected: virtual void _fake_static_method()
{
}
};
class B1 : public A
{
protected: virtual void _fake_static_method()
{
std::cout << "Hello";
}
public: static void run_fake_static_method()
{
B1* dummy = static_cast<B1*>(::operator new(sizeof(B1)));
dummy->_fake_static_method();
free(dummy);
}
}
class B2 : public A
{
public: static void run_fake_static_method()
{
B2* dummy = static_cast<B2*>(::operator new(sizeof(B2)));
dummy->_fake_static_method();
free(dummy);
}
}
Here I want to call a static method from example B1::run_fake_static_method(). In that method I want to run a member method, but I don't want to call the default constructor. I need such an implementation to remove the virtual method without a compiling error among other errors. Like a "virtual static method" I hope you understand what I want to do.
Is there a special trick that I can get this to work? :)

C++ Child class inheriting parent class constructor

I have an assignment that requires two classes to be derived from a base class. I am having issues getting the derived classes to call the base class constructor and successfully set the inherited variables. I recreated the issue with a dummy program for simplicity since the assignment is much longer.
#include <iostream>
class ParentClass {
public:
ParentClass(int theField1, int junk);
ParentClass() {}
virtual void printField();
virtual void setField(int nf);
protected:
int field1;
};
class ChildClass : public ParentClass {
public:
ChildClass(int theField1);
void printField();
void setField(int nf);
};
ParentClass::ParentClass(int theField1, int junk) {
field1 = theField1;
}
ChildClass::ChildClass(int theField1) {
ParentClass::ParentClass(theField1, 3);
}
void ParentClass::printField() {
std::cout << "The field = " << field1 << std::endl;
}
void ChildClass::printField() {
ParentClass::printField();
std::cout << "Some other stuff." << std::endl;
}
void ParentClass::setField(int nf) {
field1 = nf;
}
void ChildClass::setField(int nf) {
ParentClass::setField(nf);
}
int main() {
ChildClass* myChild = new ChildClass(777);
ChildClass child2(888);
myChild->printField();
child2.printField();
myChild->setField(10);
myChild->printField();
child2.setField(20);
child2.printField();
return 0;
}
Running this gives me the following output:
The field = 0
Some other stuff.
The field = 4197296
Some other stuff.
The field = 10
Some other stuff.
The field = 20
Some other stuff.
Why do the first two attempts not work? Calling the constructor should be initializing the variables to the value passed as a parameter, but they are not actually set until I specifically call a mutator function. I tried a third class which used the parent mutator function in its constructor rather than the parent constructor:
class StepChild : public ParentClass {
public:
StepChild(int nf);
};
StepChild::StepChild(int nf) {
ParentClass::setField(nf);
}
The object as defined in main:
StepChild* step = new StepChild(30);
step->printField();
The output:
The field = 30
Where am I going wrong that attempting to use the parent constructor is not properly initializing these variables?
I also tried changing the parent class to be not virtual, and it worked as well, so it doesn't appear to be an issue with the parent class.
Use initialiser lists:
ParentClass::ParentClass(int theField1, int junk)
: field1(theField1)
{ }
ChildClass::ChildClass(int theField1)
: ParentClass(theField1, 3)
{ }
The following - from your code - creates a temporary ParentClass object and throws it away - that has no affect on the ChildClass object under construction:
ParentClass::ParentClass(theField1, 3); // temporary
If you make the parameters match, you can also do it the c++11 way by putting
using ParentClass::ParentClass( int, int );
in your ChildClass class definition. It is the same as invoking the parent constructor from the ChildClass constructor initialiser list, but a little less esoteric.
Not sure but I find something wrong in the way you are calling base class constructor.
try this way to call base class constructor and see if the problem is solved.

c++ overriding a function only for a specific instance

I was wondering whether there's a way to override a function for a specific instance only. For ex,
class A
{
public:
...
void update();
...
}
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new A();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new A();
// ....so on.
...
}
Is there a way to achieve this?
I think virtual function is just what you want, with virtual function, different instances of the same type can have different functions, but you need to inherit the base class. for example
class A
{
public:
...
virtual void update()
{
std::cout << "Class A\n";
}
...
};
class B: public A
{
public:
virtual void update()
{
std::cout << "Class B\n";
}
};
class C: public A
{
public:
virtual void update()
{
std::cout << "Class C\n";
}
};
int main()
{
...
A *first_instance = new A();
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A *second_instance = new B();
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A *third_instance = new C();
// ....so on.
...
}
each instance in the above code will bind different update functions.
Besides, you can also use function pointer to implement your requirement, but it is not recommended. For example
class A
{
public:
A(void(*u)())
{
this->update = u;
}
...
void (*update)();
};
void a_update()
{
std::cout << "update A\n";
}
void b_update()
{
std::cout << "update B\n";
}
void c_update()
{
std::cout << "update C\n";
}
int main()
{
...
A first_instance(a_update);
// I want this to have a specific update() function.
// ex. void update() { functionA(); functionB(); ... }
A second_instance(b_update);
// I want this to have a different update() function than the above one.
// ex. void update() { functionZ(); functionY(); ...}
A third_instance(c_update);
// ....so on.
...
}
Hope helps!
Hold a function in the class.
#include <iostream>
#include <functional>
using namespace std;
class Foo
{
public:
Foo(const function<void ()>& f) : func(f)
{
}
void callFunc()
{
func();
}
private:
function<void ()> func;
};
void printFoo() { cout<<"foo"<<endl; }
void printBar() { cout<<"bar"<<endl; }
int main()
{
Foo a(printFoo);
Foo b(printBar);
a.callFunc();
b.callFunc();
}
You may have noticed that the end brace of a class is often followed by a semicolon, whereas the end braces of functions, while loops etc don't. There's a reason for this, which relates to a feature of struct in C. Because a class is almost identical to a struct, this feature exists for C++ classes too.
Basically, a struct in C may declare a named instance instead of (or as well as) a named "type" (scare quotes because a struct type in C isn't a valid type name in itself). A C++ class can therefore do the same thing, though AFAIK there may be severe limitations on what else that class can do.
I'm not in a position to check at the moment, and it's certainly not something I remember using, but that may mean you can declare a named class instance inheriting from a base class without giving it a class name. There will still be a derived type, but it will be anonymous.
If valid at all, it should look something like...
class : public baseclass // note - no derived class name
{
public:
virtual funcname ()
{
...
}
} instancename;
Personally, even if this is valid, I'd avoid using it for a number of reasons. For example, the lack of a class name means that it's not possible to define member functions separately. That means that the whole class declaration and definition must go where you want the instance declared - a lot of clutter to drop in the middle of a function, or even in a list of global variables.
With no class name, there's presumably no way to declare a constructor or destructor. And if you have non-default constructors from the base class, AFAIK there's no way to specify constructor parameters with this.
And as I said, I haven't checked this - that syntax may well be illegal as well as ugly.
Some more practical approaches to varying behaviour per-instance include...
Using dependency injection - e.g. providing a function pointer or class instance (or lambda) for some part of the behavior as a constructor parameter.
Using a template class - effectively compile-time dependency injection, with the dependency provided as a function parameter to the template.
I think it will be the best if you'll tell us why do you need to override a function for a specific instance.
But here's another approach: Strategy pattern.
Your class need a member that represent some behaviour. So you're creating some abstract class that will be an interface for different behaviours, then you'll implement different behaviours in subclasses of that abstract class. So you can choose those behaviours for any object at any time.
class A;//forward declaration
class Updater
{
public:
virtual ~Updater() {};//don't forget about virtual destructor, though it's not needed in this case of class containing only one function
virtual void update(A&) = 0;
}
class SomeUpdater
{
public:
virtual void update(A & a);//concrete realisation of an update() method
}
class A
{
private:
Updater mUpdater;
public:
explicit A(Updater updater);//constructor takes an updater, let's pretend we want to choose a behaviour once for a lifetime of an object - at creation
void update()
{
mUpdater.update(this);
}
}
You can use local classes, yet, personally, I consider the "hold function in the class" approach mentioned in the other answer better. I'd recommend the following approach only if doFunc must access internals of your base class, which is not possible from a function held in a member variable:
class ABase {
public:
void Func () { this->doFunc (); }
private:
virtual void doFunc () = 0;
public:
virtual ~ABase () { }
};
ABase* makeFirstA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "First A"; }
};
return new MyA;
}
ABase* makeSecondA () {
class MyA : public ABase {
virtual void doFunc () { std::cout << "Second A"; }
};
return new MyA;
}
int main () {
std::shared_ptr<ABase> first (makeFirstA ());
std::shared_ptr<ABase> second (makeSecondA ());
first->Func ();
second->Func ();
}
From a design patterns point of view, the "local classes" approach implements the template method pattern, while the "hold a function(al) in a member variable" approach reflects the strategy pattern. Which one is more appropriate depends on what you need to achieve.

Dependent member initialization, when reorder is not possible

#include <iostream>
class BarParent
{
public:
int x;
virtual void fuz() = 0;
};
class BarChild : public BarParent
{
public:
BarChild(int new_x){x = new_x;}
virtual void fuz(){}
};
class FooParent
{
public:
BarParent* p_barPar;
FooParent (BarChild* new_p_bar)
{
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
};
class FooChild: public FooParent
{
public:
BarChild barChild;
FooChild(int new_x):FooParent(&barChild), barChild(new_x){}
};
int main()
{
FooChild foo(60);
BarChild bar(99);
FooParent fooP(&bar);
}
Output:
-548726160
99
I understand why I am getting this result(undefined behavior), barChild is used before it is initiailized. My question is what is the 'right' to do handle this.
This is a case where design, not code needs to be fixed.
By your own design:
A BarChild must be constructed before FooParent.
A FooParent must be constructed before a FooChild.
A FooChild must be constructed before a BarChild.
When you want both FooParent and FooChild to refer to this same Bar object - as you're attempting in your code - design the parent class to manage it.
One example solution:
FooParent (BarChild* new_p_bar)
{
if ( new_p_bar == NULL )
new_p_bar = new BarChild;
p_barPar = new_p_bar;
std::cout << p_barPar->x << std::endl;
}
Here, FooChild doesn't need its own instance of this object.
Respect the order of initialization.
You can create a function inside BarParent to set the pointer p_barPar. Call the function in the constructor of FooChild.
Is there any reason you can't make barChild (in FooChild) a pointer as well?
I think you will have to find another example: this one is wrong because of the RAIII principle which is not enforced: FooParent holds a pointer on a value which it doesn't control. An interesting example of where this setup would fail is the slicing problem.
quick and dirty solution:
class FooChild: private BarChild, public FooParent
{
public:
FooChild(int new_x): BarChild(new_x), FooParent(this) {}
};