I try to write an internal class that inherits from the real class for testing. The internal class copies temporary variables pass between classes.
Example:
#include <iostream>
#include <random>
class Internal_a;
class A {
public:
A() {}
const int test() const { return std::rand() % 10; }
private:
friend class Internal_a;
};
class Internal_a : public A {
public:
int test() {
_val = A::test();
return _val;
}
int _val;
};
class C {
public:
C(const A& a) { _x = a.test() * 2; }
private:
int _x;
};
int main() {
Internal_a i_a;
C c(i_a);
std::cout << i_a._val << "\n";
}
Problem:
The i_a._val value is not a copy of the result of A::test() during the construction of the c object. This is because inheritance doesn't work that way (ok, I just learned that.)
How to write a test that checks that temporary value (A::test()) ?
Related
In multiple inheritance,where all the base class contains same function name with different functionality, we can access the protected function from particular base class using "::" scope resolution operator.
However, I tried something else. I created the objects of the base class in inside the child class. And tried calling the function using through object of that particular class.
But I was getting the following compiler error:
"‘void A::func(int&)’ is protected within this context."
Please let me know where did i go wrong.
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val(int new_val)
{
a = new_val;
a_val.func(a);
b_val.func(a);
c_val.func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}
If you want to keep your code with the base classes as having independent functionality and still remaining protected the easiest way to resolve your issue is by slightly changing the name of your protected functions and adding a public function that calls the protected members: See these class declarations for example:
class A {
public:
void func( int& a ) {
func_impl( a );
}
protected:
void func_impl( int& a ) {
a = a * 2;
}
};
class B {
public:
void func( int& b ) {
func_impl( b );
}
protected:
void func_impl( int& b ) {
b = b * 3;
}
};
class C {
public:
void func( int& c ) {
func_impl( c );
}
protected:
void func_impl( int& c ) {
c = c * 5;
}
};
class D : public A, public B, public C {
public:
int a;
A a_val;
B b_val;
C c_val;
void update_val( int val ) {
a = val;
a_val.func( a );
b_val.func( a );
c_val.func( a );
}
void check( int );
};
void D::check( int val ) {
update_val( val );
std::cout << "Value = " << a << std::endl;
}
This provides a nice public interface to call the protected member functions. This also resolves the issue of accessing the protected members. When I run your program and input a value of 5 it returns a result of 150 and works as expected.
This snippet should show you how inheritance works and when you can and can not access protected members:
class DerivedA : public Base {
public:
Base b;
void call_message() {
b.message(); // Protected Member of Base class can not be accessed
}
};
class DerivedB : public Base {
public:
void call_message() {
message(); // This works without problem!
}
};
Just as I did above one way to resolve this is by adding a public interface caller to the protected implementation.
class Base {
public:
void message() {
message_impl();
}
protected:
void message_impl() {
std::cout << "This is a protected member of Base\n";
}
};
Now you can do this:
class DerivedA {
public:
Base b;
void call_message() {
b.message(); // Accessible through public interface.
}
};
When you are in your derived class, it has access to its own ancestor methods. But it doesn't have access to your variables member protected and private methods and variables.
Redesign your code, you are trying things and contorting the other classes design for bad reasons. Francis' code is a good solution, but D doesn't need to inherit from anything.
If you don't want to create another function, you can do something like this:
#include <iostream>
using namespace std;
class A
{
protected:
void func(int & a)
{
a = a * 2;
}
};
class B
{
protected:
void func(int & a)
{
a = a * 3;
}
};
class C
{
protected:
void func(int & a)
{
a = a * 5;
}
};
class D : public A,public B,public C {
public:
int a;
void update_val(int new_val)
{
a = new_val;
this->A::func(a);
this->B::func(a);
this->C::func(a);
}
void check(int);
};
void D::check(int new_val)
{
update_val(new_val);
cout << "Value = " << a << endl;
};
int main()
{
D d;
int new_val;
cin >> new_val;
d.check(new_val);
}
This works because, this refers to the current instance of class D, and it already inherits class A, class B, class C. So you can directly access the protected functions of the respective classes.
Remember: It will not work if you have not inherited the classes.
Can I do an defined constructor which contains an object from another class?
If i can do how is defined.
this is an example.I do classes and how could be defined the constructor of class "Abonati" which contains an object "abonament"
I need that because i have another class which contain a vector of "abonati"
#pragma once
#include"abonament.h"
#include<iostream>
#include<vector>
using namespace std;
class abonati
{
char*nume_abonat;
int nr_telefon;
char *numefisier;
abonament *a;
public:
abonati();
abonati(char*, int , char *,abonament *);
abonati(abonati&a);
void Send();
~abonati();
};
`#pragma once
#include"abonati.h"
class abonament
{
protected:
int cost;
public:
abonament();
abonament(int costa);
virtual ~abonament();
};
#include "abonament.h"
abonament::abonament()
{
this->cost = 0;
}
abonament::abonament(int costa)
{
this->cost = costa;
}
abonament::~abonament()
{
}
`
I guess you would like to pass an class instance to another class constructor
Here is an example
#include <iostream>
class A
{
public:
A(int value) : m_int(value) {}
int GetInt() { return m_int; }
private:
int m_int;
};
class B
{
public:
B(A& a) : m_int(a.GetInt()) {} // Here constructor expects instance of class A
int GetInt() { return m_int; }
private:
int m_int;
};
int main()
{
A a(2);
B b(a); // Pass an object of class A to constructor of class B
std::cout << b.GetInt() << std::endl;
return 0;
}
Prints
2
I have a class derived from an interface and a friend class of the derived class. I want to access the members of derived class which is instantiated as interface. It looks like this:
Interface:
class AInterface
{
public:
virtual ~AInterface() = default;
virtual void set(int a) = 0;
};
Derived class A with friend class B:
class B;
class A : public AInterface
{
public:
~A() override {}
void set(int a) override
{
mem = a;
}
private:
friend class B;
int mem = 0;
};
class B:
class B
{
public:
B()
{
a = new A();
a->set(3);
}
int get_a()
{
// Access mem since it's a friend class
return a->mem;
}
private:
AInterface *a;
}
main:
int main()
{
B *b = new B();
std::cout << b->get_a() << std::endl;
return 0;
}
The program does not compile saying AInterface has no member named 'mem'.
Do I need getter functions in the interface and implement it in A to achieve this or is there any other way to do it?
Now work
#include <iostream>
using namespace std;
class AInterface
{
public:
virtual ~AInterface() = default;
int getMem() { return mem; }
virtual void set(int a) = 0;
protected:
int mem = 0;
};
class A : public AInterface
{
public:
~A() override {}
void set(int a) override
{
mem = a;
}
};
class B
{
public:
B()
{
a = new A{};
a->set(3);
}
int get_a()
{
// Access mem since it's a friend class
return a->getMem();
}
private:
AInterface *a;
};
int main()
{
B *b = new B();
std::cout << b->get_a() << std::endl;
return 0;
}
Method which is override by child and is pure, should be virtual.
If each class (child) Interface, variable int mem should be protected in interface.
Now works fine, like you want.
Add getter getMem()
Version with friend
#include <iostream>
using namespace std;
class AInterface
{
public:
virtual ~AInterface() = default;
virtual void set(int a) = 0;
protected:
friend class B;
int mem = 0;
};
class A : public AInterface
{
public:
~A() override {}
void set(int a) override
{
mem = a;
}
};
class B
{
public:
B()
{
a = new A{};
a->set(3);
}
int get_a()
{
// Access mem since it's a friend class
return a->mem;
}
private:
AInterface *a;
};
int main()
{
B *b = new B();
std::cout << b->get_a() << std::endl;
return 0;
}
In your class B.
class B
{
//...
int get_a()
{
return a->mem; // but a is a AInterface* !!!
}
private:
AInterface *a; // That's not an A*, but an AInterface*
};
You have 2 options.
use dynamic_cast<>
int B::get_a()
{
A* p = dynamic_cast<A*>(a);
if (p)
return p->mem;
// a is not an A*, it's another AInterface*-type object !!!
// What should you do?
throw something_or_other(); // throw?
return -1; // return an error code?
}
// or maybe add.. so you can check for errors before calling get_a()
A* B::get_A_ptr() const
{
return dynamic_cast<A*>(a);
}
dynamic_cast works fine, but can slow down your app if you need to make frequent reads of a->mem.
Store a in an A*, which is probably what you meant to do from the start...
class B
{
// ...
private:
A* a; // now a->A::mem is visible.
};
Since you explicitly call new A in B's constructor, I think option 2 is better for your case.
Big edit:
I have a code in which I have to add a constant member in a inherited class by using _elemente (which is a vector). Not to add a member in the inherited classes, just by using _elemente. In every inherited classes (let's say B, C, D and E) I withh have MAX_VAL1, MAX_VAL2 and so on with different values.
I tried:
#include <iostream>
#include <iomanip>
#include <vector>
typedef unsigned int Uint;
typedef vector<Uint> TVint;
typedef vector<Uint>::const_iterator TIterator;
class A
{
protected:
Uint _count;
TVint _elemente;
public:
//
};
class B : public A
{
const int MAX_VAL;
};
But it has a member and I don't have to have a member in the inherited class.
All the code here:
.h: http://pastebin.com/P3TZhWaV
.cpp: http://pastebin.com/ydwy2L5a
The work from the inherited classes is done using that constant members.
if MAX_VAL1 < count
{
throw Exception() {}
}
if (_elemente.size() == 0) // As _elemente is a vector from STL
{
_elemente.push_back(0);
}
for (int i = _elemente.size(); i < count; i++)
{
_elemente.push_back(_elemente[i * (i+1) / 2]);
}
}
I don't think that is correct as I have to use the Vector from STL and I don't really think that is the way the constant member from a inherited class without the actual member declared should be added.
Thanks for your help.
You could use a virtual function, something like this:
class A
{
virtual int max_val() const = 0;
protected:
Uint _count;
TVint _elemente;
public:
//
};
class B : public A
{
int max_val() const { return 42; }
};
if ( max_val() < _count ) ...
Based on other comments it seems like you want a const number that is accessible in the base class which can have a different value depending on the derived class. You could achieve that like this: https://ideone.com/JC7z1P
output:
A: 50
B: 80
#include <iostream>
using namespace std;
class Base
{
private:
const int aNumber;
public:
// CTOR
Base( const int _aNumber ) :
aNumber( _aNumber ) {}
// check value
int getNumber() const
{
return aNumber;
}
};
class A : public Base
{
public:
A() : Base( 50 ) {}
};
class B : public Base
{
public:
B() : Base( 80 ) {}
};
int main() {
A a;
B b;
std::cout << "A: " << a.getNumber() << std::endl;
std::cout << "B: " << b.getNumber() << std::endl;
return 0;
}
When you write like
class B : public A
{
const int MAX_VAL;
};
what value do you expect B's class instance to hold with current approach?
Have you tried to add ctor to B (to initialize MAX_VAL to some exact value), so that whole class definition should be like
class B : public A
{
const int MAX_VAL;
public:
B(int max_val):MAX_VAL(max_val) {}
};
Also, the code above shows a lot of unanswered questions. Some of them:
Do you really need it to be member? mark it as 'static' (static const int MAX_VAL = 5) . That would mean, every B's instance MAX_VAL would be equal
All of type redifinitions don't look meaningful. What if you use intrisic types and auto?
Usually one doesn't compare size() with 0 - just calls empty().
Have you tried to read Stroustrup or Lippman?
If you want to access it statically, you can do it by using templates :
ABase gives polymorphic access to value
A gives static access to value
B and Care examples of usage
.
// This is the polymorphic root class
class ABase
{
public:
ABase(int maxV) : _maxV(maxV) {}
int maxValue() { return _maxV; }
private:
int _maxV;
};
// This class gives static method
template<int V_MaxValue>
class A : public ABase
{
public:
A() : ABase(V_MaxValue) {}
static int maxValue() { return V_MaxValue; }
};
class B : public A<42>
{
};
class C : public A<35>
{
};
// Static access (neex explicit class call) :
// B::maxValue() => 42
// C::maxValue() => 35
//
// Polymorphic call :
// ABase* poly = new B();
// poly->maxValue() => 42
Let's say I have two classes, A and B:
class B;
class A
{
private:
int an_int;
B *something_else;
public:
A(int n) : an_int(n), something_else(nullptr) {}
};
class B
{
private:
int an_int;
A *something_else;
public:
B(int n) : an_int(n), something_else(nullptr) {}
};
How can I make it so that I don't have to prototype B in order to have a pointer to a B object in class A?
This solution is most probably what is intended in an exercise about inheritance where you can't use a forward declaration.
Instead of the forward declaration
class B;
you can define an interface like
struct I_whoop
{
virtual void whoop_whoop() = 0;
};
then let class B implement that interface, and just use a pointer to the interface.
Actually You can not if using concrete class.
But You can achieve your goal by using template parameters. Making class B a template parameter of template class A.
How can I make it so that I don't have to prototype B in order to have a pointer to a B object in class A?
Like this:
class A
{
private:
int an_int;
class B *something_else;
public:
A(int n) : an_int(n), something_else(nullptr) {}
};
class B
{
private:
int an_int;
class A *something_else;
public:
B(int n) : an_int(n), something_else(nullptr) {}
};
In C and C++ it has never been necessary for a type T to be
forward declared before the declaration of objects of type T *
(or const variants), because the declaration of a T * per se requires
the compiler only to know the size of a T *, not the size or definition
of a T, and the size of a T * is the same, regardless of T.
Here is a more fleshed-out illustration:
class A
{
private:
int an_int;
class B *something_else;
public:
A(int n, class B * pb = nullptr) : an_int(n), something_else(pb) {}
int get_int() const {
return an_int;
}
void set_B(class B * pb) {
something_else = pb;
}
class B * get_B() const {
return something_else;
}
};
class B
{
private:
int an_int;
class A *something_else;
public:
B(int n, class A * pa = nullptr) : an_int(n), something_else(pa) {}
int get_int() const {
return an_int;
}
void set_A(class A * pa) {
something_else = pa;
}
class A * get_A() const {
return something_else;
}
};
#include <iostream>
int main()
{
A a(1);
B b(2);
a.set_B(&b);
b.set_A(&a);
std::cout << a.get_B()->get_int() << std::endl;
std::cout << b.get_A()->get_int() << std::endl;
return 0;
}
Output:
2
1
(gcc 4.9.2/clang 3.5.2 -std=c++11 -Wall -pedantic)