Member function overriding accross class hierarchy - c++

I have defined a class A and derived a new class B from A .
I have overloaded SetData() function in class B.
When I tried to access SetData function of class B using object of B, compiler doesn't permit it. Why is it so ?
class A{
public :
void SetData();
};
class B : public A {
public:
void SetData(int);
};
B b;
b.SetData() ; // error

OMG, no error message. -1 for you.
But let us use telepathy and guess your error message. You're getting something like "symbol not found" because you try to call a function B::SetData() which doesn't have a body. And it must have a body even if it does nothing and even if it's declared in parent class! Try adding it into the body of your class
class B : public A {
public:
void SetData(int)
{ /* add body here */ };
};
or outside of it
class B : public A {
public:
void SetData(int);
};
void B::SetData(int)
{
//write it here
}

b.SetData(2) ; // error
I don't see any problem in calling SetData(2).
Where as if you call b.SetData() ; then there will be an error. When you define a method with same name in in derived class the base class methods with same name will be hidden in derived class.
You can make them visible in derived class by using keyword.
class A{
public :
void SetData(){}
};
class B : public A {
public:
using A::SetData;
void SetData(int){}
};
int main()
{
B b;
b.SetData() ; // error
}

What i guess you might be facing
error: unresolved external symbol
write code as suggested by Pavel Shved

Related

Ciclic class use inside another class

I have two classes inside one cpp file like this:
class A
{
private:
int somethingPrivate;
B *aReferenceToB;
public
B returnSomeB()
{
aReferenceToB->someFunction();
return *aReferenceToB;
}
};
class B
{
private:
A needed_Class_A_var;
public:
void someFunction()
{
return;
}
};
This ciclic use of these two classes, one inside another, generates all sort of errors like
error C2143: syntax error : missing ';' before '*'
How can I resolve this ciclic include problem without creating separate files for each class and using only one cpp file?
I have tried to add a class B; declaration before class A definition wich does not work properly.
Before you access members of the B class (aReferenceToB->someFunction()), or even try to return the object of B (not the pointer to B) (B returnSomeB), you need to have a complete definition of class B first.
So, just extract the returnSomeB body out of the class A definition, and put it in place where the full definition of B is known.
class B;
class A
{
private:
int somethingPrivate;
B *aReferenceToB;
public:
B returnSomeB();
};
class B
{
private:
A needed_Class_A_var;
public:
void someFunction()
{
return;
}
};
B A::returnSomeB(){
aReferenceToB->someFunction();
return *aReferenceToB;
}
Please note that if you try to write something like this:
class B;
class A
{
private:
int somethingPrivate;
B *aReferenceToB;
public:
B* returnSomeB() { return aReferenceToB; }
};
that would be valid, because you're only manipulating with the pointers here (in this case, you're not creating object of B, and you don't access any of B's members), and the size of the pointer is known at the compile time, even without class B definition.

Understanding how to solve ambiguous member requests in c++

How do I use a function in class A from class D without inheriting class A and (although I understand it's bad practise, I am not permitted to alter the inheritance at all) and not remove the inheritance from C and B in D? I cannot seem to find a way around the request for member is ambiguous error. I was (wrongly) of the understanding that no matter how far removed the
class A
{
public:
void DoEverything(int){ }
};
class B : public A
{
public:
...
};
class C : public A
{
public:
...
};
class D : public C : public B
{
public:
...
};
int main()
{
D dMan;
int i = 2;
dMan.DoEverything(i);
}
My example is loosely based on the "Ambiguous base classes (C++ only)" example found here: http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/language/ref/cplr138.htm#cplr138 but that hasn't helped me understand the problem.
First of all, to make it work just do the following changes
class B : virtual public A
...
class C : virtual public A
This problem in multiple inheritance is called the diamond problem. Check out this link to know more
http://www.cprogramming.com/tutorial/virtual_inheritance.html

Why am I getting undefined type error after a forward-declaration?

I'm using this code in C++ CLI. However this shouldn't make any difference from C++.
I'm looking for a solution to get rid of that error.
Code :
ref class B;
ref class A;
public ref class A
{
public:
A() {}
B^ b;
void HelloFromA(){
b->HelloFromB();
}
};
public ref class B
{
public :
A^ a;
B() {}
void HelloFromB(){
a->HelloFromA();
}
};
You need to move the bodies of the functions that invoke member functions on the forward-declared classes outside of the headers, to places where definitions are available:
void A::HelloFromA(){
b->HelloFromB();
}
Otherwise, the compiler knows that B is available, but it does not know that B has the HelloFromB member function that takes no arguments.

C++ reference sub class in super class

I am little bit confused on referencing a sub class inside a super class in C++.
For example, given Java :
public class Entity {
protected ComplexEntity _ce;
public Entity() {
}
public ComplexEntity getCentity() {
return _ce;
}
}
Where ComplexEntity extends the entity.It works.In the sub class I call getCentity() no errors.
Now ,in C++ when I write something like that:
#pragma once
#include "maininclude.h"
#include "ExtendedEntity.h"
using namespace std;
class EntityBase
{
public:
EntityBase(void);
EntityBase(const string &name);
~EntityBase(void);
protected:
ExtendedEntity* _extc;
string _name;
};
I am getting compiler error:
error C2504: 'Entity' : base class undefined
In the classes which inherit from this Entity.Why does that happen?
Is it completely unacceptable in C++?
May be Entity must be abstract ?
I would like to get suggestions on possible workarounds.
You may consider using CRTP, cut/paste from Wikipedia:
// The Curiously Recurring Template Pattern (CRTP)
template<class Derived>
class Base
{
Derived* getDerived() { return static_cast<Derived*>(this); }
};
class Derived : public Base<Derived>
{
// ...
};
Your code is like the following:
struct D : B {}; // error: B doesn't mean anything at this point
struct B {
D *d;
};
Your header ExtendedEntity.h is trying to use the definition of Entity before Entity is defined.
You need to change your code to this:
struct D;
struct B {
D *d;
};
struct D : B {};
A class in C++ needs to know the size of all its members and of all its superclasses. Class Entity does not know the size of it's subclass ComplexEntity, unless class ComplexEntity is defined before class Entity. But then, class ComplexEntity does not know the size of its superclass Entity.
This problem exists in C++, because class members are accessed using simple offset calculation. You can work around this, by forward declaring the derived class and using pointers as members:
class Extended; // declare the derived class
class Base { // define the base class
Extended* e; // you cannot use Extended e here,
// because the class is not defined yet.
};
class Extended : public Base {}; // define the derived class

How to skip a class with public access to a function?

I have this setup:
class A
{
public:
virtual void Function();
}
class B : private A
{
}
class C : public B
{
public:
// I want to expose A::Function() here
}
I tried to do this by adding:
class C : public B
{
public:
virtual void Function();
}
and
C::Function()
{
A::Function();
}
but I get and "inaccessible base" error.
Is it possible to do something like this?
In B you can change the accessibility of A::Function to protected:
class B : private A
{
protected:
using A::Function;
};
In C::Function (and elsewhere in C) you will then have to refer to the function as B::Function, not A::Function. You could also public: using B::Function; in C instead of implementing a C::Function that just calls B::Function.
You can't do this. The fact that B inherits from A is an implementation detail and you are not allowed to access it from C- just like you can't access B's private functions or member variables.
This would be completely legal if B inherited protected or public from A.
If you can change it to class B : protected A it should work.
Not really. The scenario you're describing would indicate that your class hierarchy needs to be reworked.