example how to do multiple inherit? - c++

Can somebody give me a example: How do i multiple inherit int, float from first class and char, string from second class into the third class ?

class A
{
private:
int i;
float f;
};
class B
{
private:
char c;
std::string s;
};
class C : public A, public B
{
};
Objects of type C now contain members i, f, c, and s. Note that you won't be able to access these members from within methods of C, since they remain private to A and B respectively. In order to access these from within C methods, they would have to have been originally declared as public or protected rather than private, but that is not good design.

Normally, you don't use multiple inheritance to get access to data (data should normally be private, so a derived class can't access it anyway).
Multiple inheritance basically produces an object with more than one set of properties. For example, consider doors, some wood and some steel:
class steel {
unsigned int AISI_number;
char Rockwell_scale;
unsigned int Rockwell_number;
};
class wood {
double density;
std::string species;
};
class door {
int width;
int height;
unsigned char num_hinges;
};
class wooden_door : public wood, public door {};
class steel_door : public steel, public door {};
This is a bit contrived, because it's probably pretty rare that we'd actually care much about the steel in a steel door (e.g., that it's 1020 steel that has been hardened to Rockwell C40), but I hope the general idea comes through anyway. [And yes, I'm aware that all the data is inaccessible, because it's all private, and there's no code to access it in any of the classes...]

Do you mean inheriting from a class with int and float field and a second class containing a char and string field?
class1
{
int anInt;
float aFloat;
}
class2
{
char aChar;
string aString;
}
class3 : public class1, public clas2
{
...
}

1) You cannon inherit from base
types.
2) Normal multiple
inheritance looks like this:
class A { /* ... */ };
class B { /* ... */ };
class C { /* ... */ };
class X : public A, private B, public C { /* ... */ };

Related

How to let a class access a private method or attribute of another class?

Considering a class with only a private attribute like:
class Example
{
private:
int number = 10;
};
If I create another class that contains a vector of Example,
is there a way to let only this class access the private attribute?
class ChangeExampleValue
{
public:
Example v[5] {*new Example,*new Example,*new Example,*new Example,*new Example};
changeNumber()
{
for(Example e : v)
{
//something that let me access the private attribute "number"
e.number*=2;
}
}
};
in this particular case the class "ChangeExampleValue" contains instances of Example, but I'm even interested in a solution for classes that haven't anything in common.
You could use a friend class.
class B;
class A {
private:
int v;
friend class B;
};
class B {
private:
B array[5]; //B has access to A's vars
};
I don't suggest you use this too often because it ruines the idea of incapsulation. You could use inheritance or simply make A public, especially if it is only a data structure with no methods.

C++ inheritance: protected variables not available

I've got the following C++ code in XCode, giving two errors I cannot make sense of:
#include <iostream>
class Buch{
public:
Buch (long int nummer = 0, char autor[25] = (char*)"", int jahr = 0, bool ausgel = false);
long int getNr();
int getJahr();
protected:
long int __nummer;
char __autor[25];
int __jahr;
bool __ausgel;
void setAusl(bool x);
bool getAusl();
};
class FachBuch : Buch {
public:
void setSWort(int sw);
int getSWort();
protected:
char __fach[15];
int __swort;
};
class UBuch : Buch {
public:
void setAlter(int a);
int getAlter();
protected:
int __kateg;
char __land[15];
private:
int _ab_alter;
};
class Bildband : UBuch {
public:
Bildband(long int nummer = 0, char autor[25] = (char*)"", int jahr = 0, int kategorie = 0, char land[15] = (char*)"");
};
Buch::Buch (long int nummer, char autor[25], int jahr, bool ausgel) {
__nummer = nummer;
//_autor = autor;
__jahr = jahr;
__ausgel = ausgel;
}
long int Buch::getNr() {
return __nummer;
}
int Buch::getJahr() {
return __jahr;
}
void Buch::setAusl(bool x) {
__ausgel = x;
}
bool Buch::getAusl() {
return __ausgel;
}
void FachBuch::setSWort(int x) {
__swort = x;
}
int FachBuch::getSWort() {
return __swort;
}
void UBuch::setAlter(int x) {
_ab_alter = x;
}
int UBuch::getAlter() {
return _ab_alter;
}
Bildband::Bildband(long int nummer, char autor[25], int jahr, int kategorie, char land[15]) {
__nummer = nummer; // error message: Cannot cast 'Bildband' to its private base class 'Buch'
//Buch(nummer, autor, jahr, false); // error message: '__nummer' is a private member of 'Buch'
}
int main () {
Bildband Masuren(356780, (char*)"Kranz", 2010, 4, (char*)"Polen");
return 0;
}
I get the following errors:
main.cpp:92:5: Cannot cast 'Bildband' to its private base class 'Buch'
main.cpp:92:5: '__nummer' is a private member of 'Buch'
My knowledge of C++ is quite limited and I had no luck googling, probably mainly because I lack the necessary C++ basic knowledge.
Can anyone explain to me why these errors occur and what terms I need to look up to understand the problem?
Thanks in advance.
They are not available because UBuch inherits Buch privately. When defining a class, inheritance is private by default.
// These two lines mean the same thing:
class UBuch : Buch
class UBuch : private Buch
All members of Buch are inherited, but those visible to UBuch are inherited as private to UBuch.
This means that code external to UBuch has no access to any members of Buch on UBuch objects, nor can it convert pointers or references to UBuch objects to pointers or references to Buch.
This includes classes that derive UBuch.
class Bildband : UBuch
Even though Buch is in the inheritance chain, its members were inherited privately by UBuch, and so Bildband has no access to the members inherited from Buch.
To fix this, you should inherit Buch publicly (and you probably want all of your other classes to inherit publicly from their respective base classes, too):
class UBuch : public Buch
Also, note that identifiers containing two consecutive underscores are reserved by the environment, so all such identifiers in your code (__nummer, __autor, etc.) cause undefined behavior.
If you don't define an access-specifier, the compiler will default to private inheritance for classes. Simply prefix your UBuch class and Buch class with "public" like so:
// ...
class UBuch : public Buch {
// ...
class Bildband : public UBuch {
I assume "public" here, since I guess that you want to provide access to the methods like getNr / getJahr from users of BildBand as well.
./regards
Florian
EDIT: See comments below
The type of inheritance effects which members are inherited:
public inheritance means only public members are inherited.
protected inheritance means public members are inherited and protected members are inherited as protected as well.
private inheritance means public members are inherited and protected members are inherited as private.
Here you are inheriting privately by default.

why getting errors in c++ program?

I think I have coded everything correctly in this program but still getting errors.
The object si it says it's not accessible.
#include<conio.h>
#include<iostream.h>
class s_interest
{
int p,t;
float r;
s_interest(int a, int b, float c)
{
p=a;
r=b;
t=c;
}
void method()
{
int result=(float)(p*t*r)/100;
cout<<"Simple interest:"<<result;
}
};
void main()
{
int pr,ti;
float ra;
cout<<"\n Enter the principle, rate of interest and time to calculate Simple Interest:";
cin>>pr>>ti>>ra;
s_interest si(pr,ti,ra);
si.method();
}
When the compiler tells you that something is not accessible, it's talking about the public: vs. protected: vs. private: access control. By default, all members of a class are private:, so you cannot access any of them from main(), including the constructor and the method.
To make the constructor public, add a public: section to your class, and put the constructor and the method there:
class s_interest
{
int p,t;
float r;
public: // <<== Add this
s_interest(int a, int b, float c)
{
...
}
void method()
{
...
}
};
Default member access for a class is private (whereas the default for struct is public). You need to make the constructor and method() public:
class s_interest
{
int p,t; // private
float r; // also private
public: // everything that follows has public access
s_interest(int a, int b, float c) { .... }
void method() { ....}
};
Note also that void main() is not standard C++. The return type needs to be int, so you need
int main()
{
...
}
And finally, iostream.h is not a standard C++ header. You need to include <iostream> if you are using a standards compliant C++ implementation.
Following High Integrity C++ Coding Standard guidelines, always declare first public, then protected and private members. See Rule 3.1.1 of hicpp-manual-version-3-3.pdf
All the variables & functions in your class are private. This is the default when access is not specified with the private: , protected: and public: specifiers. I suggest you have a good read of a tutorial - google C++ classes.
also it is int main() and never void main()
The problem is due to access specifiers. By default class methods and data members are private. Make your data members private and methods public. so you can set the private data members value using public methods.
class{
private:
int a;
int b;
int c;
public:
void method();
void print_sum();
};

Class within class - incomplete type is not allowed

class Publicatie{
public:
class Carte : public Publicatie{
private:
char* autor;
};
class Revista : public Publicatie{
private:
char* frecventa_aparitie;
int numar;
};
private:
int cota;
char* titlu;
char* editura;
int anul_aparitiei;
int tiraj;
Carte* c;
Revista* r;
public:
//some methods...
}
This is the code, i'm declaring the class Carte and Revista inside the class Publicatie and i need to have private members Carte and Publicatie. I really don't know how to do the design with inheritance with these classes. I get the error in the title for the inheritance :public Publicatie and i thought that it will work because the class is already created ( even though it's private members were not created yet).
your design is wrong. you're trying to define a class, and in it's definition you're trying to use from itself; it is a logical paradox.
from what i can understand from your code, you're trying to create a class named Publicatie that represents a publication (or a post) and it has two other variants, named Carte and Revista. if this is the case, why the Publicatie needs to have two private members of type Carte and Revista? maybe you can remove these two members from it.
or maybe you can move some of their shared members (such as titlu, tiraj and...) to another class that is abstract, and then define Publicatie, Carte and Revista such that all of them inherit from the same parent class.
hope these work.
You can only inherit from a class that is a complete type. However, you don't need to have the nested class definition inside your ambient class definition. Instead, you can do it like so:
struct Foo
{
struct Bar;
Bar * p;
int get();
};
struct Foo::Bar : Foo
{
int zip() { return 4; }
};
int Foo::get() { return p->zip(); }

Using a base-class object to represent its derived-class objects

I need a way for a single variable to represent two kinds of objects derived from the same base class.
It's kinda hard to describe but I'll try the best:
Say the base class:
class Rectangle
{
float w;
float h;
const float area() {return w*h;}
};
And the two derived classes:
class Poker : Rectangle
{
int style; // Diamond, Club, ....
int point; // A~10, J, Q, K
};
class BusinessCard : Rectangle
{
string name;
string address;
string phone;
};
Now is it possible to declare an object, which could be either a poker or a business-card?
'cuz the usage below is illegal:
Rectangle* rec;
rec = new Poker();
delete rec;
rec = new BusinessCard();
Polymorphism might be a way but since it's only good for changing base-class' member attributes, I need this object to be able to represent exactly either of the derived objects.
EDIT:
Thanks for the all the answers. The public inheritance , the virtual destructor and even the boost::variant typedef are all fantastic hints.
You can do that. The problem is the inheritance modifier for classes is private. Most of the time, private inheritance is not what you want to use. Instead, declare it explicitly as public:
class Rectangle
{
float w;
float h;
const float area() {return w*h; }; // you missed a semicolon here, btw
virtual ~Rectangle() { } // to make `delete` work correctly
};
class Poker : public Rectangle // note the public keyword
{
int style; // Diamond, Club, ....
int point; // A~10, J, Q, K
};
class BusinessCard : public Rectangle
{
string name;
string address;
string phone;
};
Then your code snippet should work.
You need to change the qualifier for the inheritence to public.
class Poker : public Rectangle
{
int style; // Diamond, Club, ....
int point; // A~10, J, Q, K
};
class BusinessCard : public Rectangle
{
string name;
string address;
string phone;
};
is what you want. Now both classes, BusinessCard and Poker are of type Rectangle.
I need this object to be able to
represent exactly either of the
derived objects.
Don't know if I understand it correct but have a look at boost::variant
typedef boost::variant<Poker, BusinessCard> PokerOrBusinessCard
Now you can access the derived classes with a boost variant visitor class.
Maybe this can be a solution.
I think what you may be looking for is multiple inheritance, where an object can sometimes be a Poker and sometimes a BusinessCard.
See here for a tutorial:
http://www.deitel.com/articles/cplusplus_tutorials/20060225/MultipleInheritance/index.html
Note that you can decide to make it one or the other if you wish, it does not have to be both all of the time, which may satisfy what you need.
Change the subclasses to use public derivation and your code works, with some cleanup. You should also use virtual destructors so the delete works correctly.
class Rectangle
{
float w;
float h;
const float area()
{
return w*h;
}
public:
virtual ~Rectangle(){};
};
class Poker : public Rectangle
{
int style; // Diamond, Club, .... int point; // A~10, J, Q, K
};
class BusinessCard : public Rectangle
{
string name;
string address;
string phone;
};