C++ inheritance: protected variables not available - c++

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.

Related

Dont allow access to member variable directly within same class

I am not sure is my question is right or not? But let me still try to ask once.
I have a Class with have few member variables defined. As per OO concepts, every member function can access , all member variables of its class.
But I want these member variable to be accessed via specific methods (Lets say Getters) , even within same class member functions.
It there any way to do it?
class A {
public:
void func1();
void func2();
B getB();
private:
B b;
}
void A::func1() {
b.functionFromB(); // function uses member variable b directly
}
void A::func2() {
B b1=getB(); // function ask for B from a function and then uses it. // I need something like this... And ensure each function uses same way otherwise there should be warning...
b1.functionFromB();
}
Thanks,
Kailas
No, there is not. You can do it via encapsulation and inheritance like:
class shape
{
private:
int angles;
protected:
shape(int angles_):angles(angles_){};
int getAngles() const;
}
class square : private shape
{
public:
square():shape(4){}
void doSth()
{
\\ you can access angles only via getAngles();
}
}
Any private members of the class can be accessed from within the class, but not by users of the class. So it looks like you need private members and public methods that allow access to them.
class A
{
private:
int a;
public:
int getA() {return a;}
};
int main()
{
A inst;
int t;
inst.a =5; // error member a is private
t = inst.getA(); //OK
}
The concept extends fine to nested class declarations in case you only want to allow instance of a class to be created from another class; details here
As others have said - you have to add an additional layer.
If you want to give access to specific methods then you can use the friend keyword. E.g.
// Public.h
#pragma once
class Public
{
public:
Public();
int GetI() const;
float GetF() const;
private:
std::unique_ptr<Private> p_;
};
//Public.cpp
#include "Public.h"
Public::Public()
: p_(new Private)
{
}
int Public::GetI() const
{
return p_->i_;
}
float Public::GetF() const
{
return p_->f_;
}
// Private.h
#pragma once
class Private
{
friend int Public::GetI() const;
friend float Public::GetF() const;
int i_;
float f_;
};
Keep in mind that every friend method can access ALL private members.
If you really really want to limit which methods can access which members then you can wrap each member in a separate class/struct and make only the getter/setter of that member a friend of that class/struct but I would not recommend this approach.

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 declaration over different files

I am not able to find a similar question else where on this site, but is it possible to declare a class over two different files.
for example, all public class components in a file and privates and others in a different file.
publics.h
class test {
public:
int geta();
void seta(int);
};
privates.h
class test {
private:
int a;
};
The above way is definitely wrong, but is there any such method.
There is a way to get something quite similar: private inheritance.
// private.hpp
class test_details {
protected:
int a;
};
// public.hpp
#include "private.hpp"
class test : private test_details {
public:
int geta() const { return a; }
void seta(int i) { a = i; }
};
Note that you will still need to (indirectly) include the private header in any module that uses the public class, so you're not really hiding anything this way.
Not like that, but the pimpl idiom (or opaque pointer, or Chesshire cat) can help you achieve similar functionality - you can provide a public interface where all implementation details are hidden in an implementation member.
C++ doesn't support partial classes.
Also, note that what you have there are class definitions, not declarations. C++ mandates that if multiple definitions of a class are available, they must be identical, otherwise it's undefined behavior.
This is a good use case for an abstract base class
//File test.h
class test {
public:
virtual ~test() {}
virtual int geta()=0;
virtual void seta(int)=0;
};
//File test_impl.h
class test_impl : public test {
public:
int geta() { return a; }
void seta(int a ) { a = v; }
private:
int a;
};

Value access in C++

HI,
I have two clases A and B,
Here A is inheriting B and now i want to access a variable in B from A, I included A header in B and tried to access but showing some error in QObject.
Is it possible to acces like this.. Please help
Not sure i get your Q correctly....
class A {
public:
int nValueA;
protected:
int nValueB;
private:
int nValueC;
};
class B : public A {
public:
B();
int x, y, z;
};
B::B():
x(nValueA), //-->OK
y(nValueB), //-->OK
z(nValueC) //-->error due to child can't inherit parent's private member
{}
void main(){
B object;
object.nValueA = 888; //--> valid
object.nValueB = 888; //--> error since protected member is not accessible
object.nValueC = 888; //--> error since private member is not accessible
}
Possible solution:
class A {
public:
int nValueA;
int nValueB;
int nValueC;
};
Is your member variable private? Then you cannot, declare it protected.

example how to do multiple inherit?

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 { /* ... */ };