abstract base classes, multiple inheritence, and common pure virtual methods - c++

The following test code seems to indicate that if a class has two abstract base classes with common pure virtual methods, then these methods are "shared" in the derived class.
#include <iostream>
#include <string>
using namespace std;
struct A
{
virtual string do_a() const = 0;
virtual void set_foo(int x) = 0;
virtual int get_foo() const = 0;
virtual ~A() {}
};
struct B
{
virtual string do_b() const = 0;
virtual void set_foo(int x) = 0;
virtual int get_foo() const = 0;
virtual ~B() {}
};
struct C : public A, public B
{
C() : foo(0) {}
string do_a() const { return "A"; }
string do_b() const { return "B"; }
void set_foo(int x) { foo = x; }
int get_foo() const { return foo; }
int foo;
};
int main()
{
C c;
A& a = c;
B& b = c;
c.set_foo(1);
cout << a.do_a() << a.get_foo() << endl;
cout << b.do_b() << b.get_foo() << endl;
cout << c.do_a() << c.do_b() << c.get_foo() << endl;
a.set_foo(2);
cout << a.do_a() << a.get_foo() << endl;
cout << b.do_b() << b.get_foo() << endl;
cout << c.do_a() << c.do_b() << c.get_foo() << endl;
b.set_foo(3);
cout << a.do_a() << a.get_foo() << endl;
cout << b.do_b() << b.get_foo() << endl;
cout << c.do_a() << c.do_b() << c.get_foo() << endl;
}
This code compiles cleanly in g++ 4.1.2 (admittedly old), using -std=c++98 -pedantic -Wall -Wextra -Werror. The output is:
A1
B1
AB1
A2
B2
AB2
A3
B3
AB3
This is what I desire, but I question whether this works generally, or only "by accident." Fundamentally, this is my question: can I depend on this behavior, or should I always inherit from a virtual base class for this type of scenario?

Don't make it harder than it is. A function with the same signature as a virtual function in a base class overrides the base version. Doesn't matter how many bases you have, or whether another base has a virtual function with the same signature. So, yes, this works.

Related

Static_cast to a non base class of the dynamic type

I have this program from an exercise, and I don't understand how the static_cast is working here:
#include <iostream>
using namespace std;
class A {
public:
virtual void f() const { cout << " A::f "; }
virtual void g() { cout << " A::g "; }
virtual A* n() { cout << " A::n "; return this; }
virtual void t() { cout << " A::t "; }
};
class B: public A {
public:
virtual void f() const { cout << " B::f "; }
void g() { cout << " B::g "; A::n(); }
A* n() { cout << " B::n "; return this; }
void t() { cout << " B::t "; }
};
class C: public A {
public:
virtual void f() { cout << " C::f "; }
void g() const { cout << " C::g "; }
};
int main() {
A* q2 = new B();
A* q3 = new C();
(static_cast<C*>(q2))->g(); cout << endl;
(static_cast<C*>(q2))->t(); cout << endl;
(static_cast<B*>(q3->n()))->f(); cout << endl;
return 0;
}
The output of this is:
C::g
B::t
A::n A::f
Can someone explain how it can take the function in C if C has never been constructed for the pointer q2? How does the static_cast work in this case?
The cast does not "work". You pretend to have a pointer to an instance of C but the pointer does not point to an instance of C. Using that pointer to call a method is undefined.
Your code has undefined behavior. Compilers are not required to diagnose undefined behavior and there are no restrictions on the compilers output. The output of this code could be anything.
PS: You should use the override specifier when overriding virtual methods. In this code it looks like you wanted C::f to override A::f, but it does not, and this will become apparent when you use override.
PS2: Calling a non-static method on a pointer of wrong type can sometimes appear to work when the method is not actually using this. Thats why you see "ok" output. However, that does not make it less wrong.

Private Data member is inaccessible in Friend Function

The private data member is inaccessible. Although i have declared function as friend of class.
Can anyone help me.
class ONE;
class TWO {
public:
void print(ONE& x);
};
class ONE {
private:
int a, b;
public:
friend void TWO::print(ONE& x);
ONE() : a(1), b(2) { }
};
void TWO::print(ONE& x) {
cout << "a is " << x.a << endl;
cout << "b is " << x.b << endl;
}
int main() {
ONE xobj;
TWO yobj;
yobj.print(xobj);
}
Error Picture is attached.

Dynamic binding and static

I guess i am having some trouble in understanding dynamic bynding.
Suppose we are having 2 classes:
class a1{ //..
virtual void print() const;
};
class a2:a1{ //...
void print() const override;
};
Why is the following true:
a2 item_son;
a1 &item_father = item_son;
item_father->print();
the print called is the one of the son.
Actually, the OP did realize the meaning of virtual overloading vs. non-virtual overloading of functions. However, I got my sample running, hence, I'd like to publish it:
#include <iostream>
class A1 {
public:
virtual void print() const
{
std::cout << "A1::print() called." << std::endl;
}
};
class A2: public A1 {
public:
void print() const override
{
std::cout << "A2::print() called." << std::endl;
}
};
class B1 {
public:
void print() const
{
std::cout << "B1::print() called." << std::endl;
}
};
class B2: public B1 {
public:
void print() const
{
std::cout << "B2::print() called." << std::endl;
}
};
using namespace std;
int main(void)
{
A2 a2;
cout << "Calling a2.print(): ";
a2.print();
A1 &a1 = a2;
cout << "Calling a1.print(): ";
a1.print();
B2 b2;
cout << "Calling b2.print(): ";
b2.print();
B1 &b1 = b2;
cout << "Calling b1.print(): ";
b1.print();
return 0;
}
Output:
Calling a2.print(): A2::print() called.
Calling a1.print(): A2::print() called.
Calling b2.print(): B2::print() called.
Calling b1.print(): B1::print() called.
Life demo on ideone

C++ How to call a derived base class function from main

I have three classes that each inherit from the other: A is inherited by B is inherited by C. I also have one virtual function in each of these classes. I want to create an A-class pointer holding a C-class object and call the B-class function like so:
class A
{
public:
virtual void doStuff() = 0;
};
class B : public A
{
public:
virtual void doStuff() override;
};
class C : public B
{
public:
void doStuff() override;
};
void B::doStuff()
{
std::cout << "Starting doStuff in B\n";
doStuff();
std::cout << "Ending doStuff in B\n";
}
void C::doStuff()
{
std::cout << "doStuff in C\n";
}
int main()
{
A *pointer = new C();
pointer->B::doStuff(); // This doesn't work
}
If I change my main slightly, I get the correct output:
int main()
{
B *pointer = new C(); // Changed A to B
pointer->B::doStuff();
}
Output
Starting doStuff in B
doStuff in C
Ending doStuff in B
How can I change my original code to use an A-class pointer and preferably only one function name?
The issue is that B::doStuff, which refers to the implementation of doStuff at class B, is not a member of A. If you are sure that the pointer is actually pointing to an instance of B or something derived from B, then you could write the following:
int main()
{
A *pointer = new C();
reinterpret_cast<B*>(pointer)->B::doStuff(); // This should work
}
If you cannot be sure about the instance type, use a dynamic_cast.
A pointer of type A can't know for certain that the B version of doStuff is accessible by default; you need to cast the pointer first.
int main()
{
A *pointer = new C();
if(B *b_ptr = dynamic_cast<B*>(pointer))
b_ptr->B::doStuff(); //Will only be executed if dynamic_cast was successful
}
Also, if you're going to use polymorphism like this, make sure you make A's destructor virtual as well, or cleanup won't behave.
class A
{
public:
virtual void doStuff() = 0;
virtual ~A() noexcept = default;
};
Here is some sample code to show why I want to do this. This code will output syntax similar to XML. Calling the "middle" class's function allows me to surround any derived class with the correct "IdentifiedRegion" tags.
#include <iostream>
#include <string>
#include <vector>
class Region
{
public:
virtual void doStuff(std::string tabs) = 0;
};
class IdentifiedRegion : public Region
{
public:
virtual void doStuff(std::string tabs) override;
};
class CircularRegion : public Region
{
public:
CircularRegion(int latitudeIn, int longitudeIn, int radiusIn) : latitude(latitudeIn), longitude(longitudeIn), radius(radiusIn) {}
void doStuff(std::string tabs) override;
private:
int latitude;
int longitude;
int radius;
};
class CountryRegion : public IdentifiedRegion
{
public:
CountryRegion(int countryCodeIn) : countryCode(countryCodeIn) {}
void doStuff(std::string tabs) override;
private:
int countryCode;
};
class StateRegion : public IdentifiedRegion
{
public:
void doStuff(std::string tabs) override;
StateRegion(std::string abbreviationIn) : abbreviation(abbreviationIn) {}
private:
std::string abbreviation;
};
void IdentifiedRegion::doStuff(std::string tabs)
{
std::cout << tabs << "<IdentifiedRegion>\n";
doStuff(tabs + "\t");
std::cout << tabs << "</IndentifiedRegion>\n";
}
void CircularRegion::doStuff(std::string tabs)
{
std::cout << tabs << "<CircularRegion>\n";
std::cout << tabs << "\t" << "<latitude>" << latitude << "</latitude>\n";
std::cout << tabs << "\t" << "<longitude>" << longitude << "</longitude>\n";
std::cout << tabs << "\t" << "<radius>" << radius << "</radius>\n";
std::cout << tabs << "</CircularRegion>\n";
}
void CountryRegion::doStuff(std::string tabs)
{
std::cout << tabs << "<CountryRegion>\n";
std::cout << tabs << "\t" << "CountryCode>" << std::to_string(countryCode) << "</CountryCode>\n";
std::cout << tabs << "</CountryRegion>\n";
}
void StateRegion::doStuff(std::string tabs)
{
std::cout << tabs << "<StateRegion>\n";
std::cout << tabs << "\t" << "<Abbreviation>" << abbreviation << "</Abbreviation>\n";
std::cout << tabs << "</StateRegion>\n";
}
int main()
{
Region *country = new CountryRegion(12);
Region *state = new StateRegion("WA");
Region *radius = new CircularRegion(10, 20, 30);
reinterpret_cast<IdentifiedRegion*>(country)->IdentifiedRegion::doStuff("");
reinterpret_cast<IdentifiedRegion*>(state)->IdentifiedRegion::doStuff("");
radius->doStuff("");
}

Redefining static const values in derived classes C++

If I create a static const in the base class of my hierarchy, can I redefine its value in a derived class?
edit:
#include <iostream>
class Base
{
public:
static const int i = 1;
};
class Derived : public Base
{
public:
static const int i = 2;
};
int main()
{
std::cout << "Base::i == " << Base::i << std::endl;
std::cout << "Derived::i == " << Derived::i << std::endl;
Base * ptr;
ptr= new Derived;
std::cout<< "ptr=" << ptr->i << std::endl;
return 0;
}
...ptr refers to Base::i, which is undesirable.
Access via ptr to static members is via its declared type Base * and not its runtime type (sometimes Base *, sometimes Derived *). You can see this with the following trivial extension of your program:
#include <iostream>
class Base
{
public:
static const int i = 1;
};
class Derived : public Base
{
public:
static const int i = 2;
};
int main()
{
std::cout << "Base::i == " << Base::i << std::endl;
std::cout << "Derived::i == " << Derived::i << std::endl;
Base *b_ptr = new Derived;
std::cout<< "b_ptr=" << b_ptr->i << std::endl;
Derived *d_ptr = new Derived;
std::cout<< "d_ptr=" << d_ptr->i << std::endl;
return 0;
}
Output:
Base::i == 1
Derived::i == 2
b_ptr=1
d_ptr=2
No. It's const, so you cannot modify its value.
But you can declare a new static const of the same name for the derived class, and define its value there.
#include <iostream>
class Base
{
public:
static const int i = 1;
};
class Derived : public Base
{
public:
static const int i = 2;
};
int main()
{
std::cout << "Base::i == " << Base::i << std::endl;
std::cout << "Derived::i == " << Derived::i << std::endl;
return 0;
}
you must initiate the const memember variable in the Constructor member initialization list.
you can not modify the const variable.