EDIT: declaring them private was a typo, I fixed it:
Relating to another question, if I declared a static variable in a class, then derived a class from that, is there any way to declare the static variable as individual per each class. Ie:
class A:
{
public:
static int x;
};
class B:A
{
public:
const static int x;
};
does that define TWO DIFFERENT static variables x, one for A and one for B, or will I get an error for redefining x, and if I do get an error, how do a I create two seperate static variables?
When you're using static variables, it might be a good idea to refer to them explicitly:
public class B:A
{
public const static int x;
public int foo()
{
return B::x;
}
}
That way, even if the class "above" yours in the hierarchy decides to create a similarly-named member, it won't break your code. Likewise, I usually try to us the this keyword when accessing normal member fields.
Updated to use C++ syntax.
That creates two separate static variables.
Note that you have implicitly declared these private:
class A:
{
private:
static int x;
};
class B:A
{
private:
const static int x;
};
Which means the variables are not in competition with each other.
As already said, that creates two separate variables :
A::x;
// and
B::x;
In fact if you try to use just 'x' in a method of B, only the closer scope definition will be used until you are more precise :
#include <iostream>
class A
{
protected:
static int x;
public:
A() { x = 7; }
};
int A::x = 22;
class B:A
{
static const int x = 42;
public:
int a_x() const { return A::x; }
int b_x() const { return B::x; }
int my_x() const { return x; } // here we get the more local variable, that is B::x.
};
int main()
{
B b;
std::cout << "A::x = " << b.a_x() << std::endl;
std::cout << "B::x = " << b.b_x() << std::endl;
std::cout << "b's x = " << b.my_x() << std::endl;
std::cin.ignore();
return 0;
}
Outputs:
A::x = 7
B::x = 42
b's x = 42
Someone mentioned that accessibility might limit accessibility : making the base variable private will not make it accessible to the child class.
However, if the variable have to be protected or public, use an explicit access method or rely on the local scope rule I just demonstrated.
If you want a static variable that is individual to each class that uses A - you can use a template class.
For e.g.
template<class T> struct A
{
A() { ++s_var; }
static int s_var;
};
template<class T> int A<T>::s_var;
stuct B :A<B> {
B() { ++s_var; } // this is a different s_var than the one used by 'C' below
};
struct C : A<C> {
C() { ++s_var; } // this is a different s_var than the one used by 'B'
};
Related
Suppose I have two classes with the same name in the same namespace in two different files.
This is so I can construct another object with each of the two classes, following the same interface but with some functions that behave differently.
For the differently behaving functions, I will redefine them in one instance of the class.
For the functions behaving the same way, I want to construct an instance of the other class and forward calls.
Is there a way to do this? Clearly I can't have two classes in the same namespace, but perhaps I can redefine the namespace/classname of the class I want to be a member in order to forward calls?
For example:
//file_1.h
namespace x {
class y {
}
}
//file_2.h
#include "file_1.h"
namespace x {
class y {
// member of same class in the other file
y memberName;
}
}
You can not modify a class after it has been declared and you can not declare two different classes with the same name.
You can declare a class hierarchy with virtual methods and use a pointer to the base. For example:
class A {
public:
virtual void f() = 0;
};
class B : public A {
void f() override {std::cout << "B" << std::endl;}
};
class C : public A {
void f() override {std::cout << "C" << std::endl;}
};
int main()
{
A *a1 = new B;
A *a2 = new C;
a1->f(); // B
a2->f(); // C
return 0;
}
Although both a1, a2 are pointers to A, the code will print:
B
C
If you do not want to made this class hierarchy public, you can use the pimpl technique. It allows you to hide the real implementation of a class.
For example:
// File: A.h
class A {
class AImpl;
std::unique_ptr<AImpl> m_pimpl;
public:
explicit A();
void f();
};
// File A.cpp
class A::AImpl {
public:
void f() { std::cout << "A" << std::endl;};
};
A::A() : m_pimpl(new AImpl) {
}
void A::f() {
m_pimpl->f();
}
Now, you can define inside your cpp file the implementation of class AImpl. You can even use a class hierarchy for AImpl to create different behaving objects depending on the class that you have created internally.
Suppose I have two classes with the same name in the same namespace in two different files.
Then you have violated a rule called thd ODR or one definition rule. Doing so makes your program ill-formed, no diagnostic required.
If you have a class Alice that wants tomuse another class Bob, but you want two different definitions for how Bob works, the solutions are called "polymorphism".
Polymorphism is the ability for two or more classes to substitute for one.
There are three simple forms of polymorphism. There is using a virtual interface and runtime polymorphism. There is using templates and compile time pokymorphism. Then there is type erasures via function pointers.
The easiest is defining a virtual interface.
struct IBob {
virtual int count() const = 0;
virtual ~IBob() {}
};
struct Alice {
std::unique_ptr<IBob> my_bob = nullptr;
void do_stuff() const {
if(my_bob) std::cout << "Count is:" << my_bob->count() <<"\n";
}
};
now we can define two implementations of IBob:
struct Bob0:IBob{
int count() const final { return 7; }
};
struct Bob1:IBob{
std::unique_ptr<IBob> pBob;
int count() const final {
if(pBob) return pBob->count()*2 +1;
else return 1;
}
};
now Bob1 has a IBob, and it uses that IBob to implement its own count.
The template way looks like:
template<class Bob>
struct Alice {
Bob my_bob;
void do_stuff() const {
std::cout << "Count is:" << my_bob.count() <<"\n";
}
};
and the various Bob implementations need no virtual or inheritance. Here you must pick which Bob at compile time at each point of use.
The manual function pointer type erasure solution is more complex. I'd advise against it.
When you include a file is like adding the content to that cpp file.
So that means you will have the same name for different classes.
There is a possibility to use the same name by using typedef.
class A {
public:
static void func() {}
};
class B {
public:
static void func() {}
};
void funcA() {
typedef A C;
C::func();
}
void funcB() {
typedef B C;
C::func();
}
int main()
{
funcA();
funcB();
return 0;
}
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
I've been trying to write up a code to implement a member function that could access private data of a class by declaring it as a friend within the class. But my code is failing and I can't seem to figure out what's wrong with it:
#include <iostream>
using namespace std;
class A;
class B
{
private:
int b; // This is to be accessed by member function of A
public:
friend void A::accessB();
};
class A
{
private:
int a;
public:
void accessB();
};
void A::accessB()
{
B y;
y.b = 100;
cout << "Done" << endl;
}
int main(void)
{
A x;
x.accessB();
}
I am trying to access the private contents of B making use of getAccessB function which is member function of A. I have declared it as a friend. What's wrong with this?
A::accessB is not declared at the point of the friend declaration, so you can't refer to it. You can fix this by shifting the order of definitions and declarations such that A::accessB is visible to B:
class A
{
private:
int a;
public:
void accessB();
};
class B
{
private:
int b;
public:
friend void A::accessB();
};
void A::accessB()
{
B y;
y.b = 100;
cout << "Done" << endl;
}
Note that making a function a friend just so that it can modify your private state is a bad code smell. Hopefully you are just doing this to understand the concepts.
The ordering. If you are referring to A::accessB, A must be declared by that point. Place the A class above the B, and it will work fine.
I have multiple classes that need to share a single instance of another class. Publicly it should be unknown that this class exists. Is it appropriate to do something like the following? (Was tested as written)
#include <iostream>
class hideme
{
private:
int a;
public:
void set(int b) { a = b; }
void add(int b) { a += b; }
int get() { return a; }
hideme() : a(0) { }
};
class HiddenWrapper
{
protected:
static hideme A;
};
hideme HiddenWrapper::A;
class addOne : public HiddenWrapper
{
public:
void add() { A.add(1); }
int get() { return A.get(); }
};
class addTwo : public HiddenWrapper
{
public:
void add() { A.add(2); }
int get() { return A.get(); }
};
int main()
{
addOne a;
addTwo b;
std::cout << "Initialized: " << a.get() << std::endl;
a.add();
std::cout << "Added one: " << a.get() << std::endl;
b.add();
std::cout << "Added two: " << b.get() << std::endl;
return 0;
}
For what it's worth, hideme is part of a library I'm attempting to design a facade around, and the other classes have members from the library that interact with the static hideme.
Additionally, if the header file written for HiddenWrapper has no corresponding source file, is that the best place to define its static member? With an include guard.
Is there any other method to solve this problem? As far as I could imagine (not terribly far) I could only solve it otherwise with friendship, which I am wary of.
You can prevent access to a class by not making it accessible outside the translation unit that uses it.
// public_header.h
class A {
void bar();
};
class B {
void foo();
}
// private_implementation.cpp
#include "public_header.h"
namespace {
class hidden { void baz() {} };
hidden h;
}
void A::bar() {
h.baz();
}
void B::foo() {
h.baz();
}
This class will be usable only by A::bar and B::foo. The type hidden and the variable h still technically have external linkage, but no other translation unit can say their names.
Sometimes it is a better idea to inject shared ressources (by reference or pointer) through the constructor (also known as composition instead of inheritance). This way gives you the ability to share or not (e.g. to have a thread-safe variant of your code which is not). See http://de.wikipedia.org/wiki/Inversion_of_Control principle for more info.
This implements a singleton around some other class and hides it from
users:
class hideme {};
// fwd declarations
class x;
// library internal
class S
{
S() = delete;
S(S const&) = delete;
void operator=(S const&) = delete;
private:
static hideme& getInstance()
{
static hideme instance;
return instance;
}
friend x;
};
// library classes
class x {
hideme& s;
public:
x() : s(S::getInstance()) {}
};
int main()
{
x x;
return 0;
}
This does not handle cases where you actually want the hideme
instance to be destroyed when no other object is using it anymore. For
that you need to get a little bit more inventive using reference
counting.
I also should say that I think this is a bad idea. Singletons almost
always are.
Generally, the best approach, if you have a variable in the main part, and want to share it with all classes.
For example, if class X makes a change on this var, the change happened to the var in the main as well: you can use EXTEND
************************ The main *********************
#include <iostream>
using namespace std;
#include "Game.hpp"
//0: not specified yet; 1:singlemode; 2:multiplayerMode
int playingMode = 0;
int main()
{
Game game;
game.Run();
std::cout<< playingMode << std::endl;
return 0;
}
*********************** Class X *****************
#include <iostream>
using namespace std;
extern int playingMode;
....
....
if(m_isSinglePressed)
{
playingMode = 1;
...
}
else if(m_isMultiPressed)
{
playingMode = 2;
...
}
https://stackoverflow.com/a/8839647/462608
Use the static initializer:
public class MyClass
{
static {
//init
}
}
Can something similar be done in C++?
Actually, I need to initialize some variables, but I don't want to create an object.
If the variables are static members, not only are you able to initialize them, but you must initialize them.
There's no direct equivalent of Java initializer lists, but something similar can be done calling a function to initialize a static member:
class X
{
static bool x;
}
bool foo()
{
//initialization code here
}
bool X::x = foo();
This is for cases with intense logic. If all you want is to initialize static members, just do it similar to X::x.
Actually, I need to initialize some variables, but I don't want to create an object.
If the variables are outside the class, initialize them directly (don't need calling code for that).
If the variables are static members of the class, use one of the above approaches.
If the variables are non-static members, they simply don't exist without an object.
Static variables of a class are initialized in .cpp file:
MyClass.h
class MyClass {
public:
static void f1();
static void f2();
private:
static int a1;
static int a2;
static int a3;
};
MyClass.cpp
int MyClass::a1 = 7;
int MyClass::a2 = 8;
int MyClass::a3 = MyClass::a1 + MyClass::a2;
void MyClass::f1()
{
a1 = 7;
}
void MyClass::f2()
{
cout << a2 << endl;
}
If you want non trivial initialization of static member variables - group them in inner class with constructor:
MyClass.h
class MyClass {
public:
static void f1();
static void f2();
private:
struct Data {
Data();
int a1;
int a2;
int a3;
};
static Data data;
};
MyClass.cpp
MyClass::Data MyClass::data;
MyClass::Data::Data() : a1(0), a2(0), a3(0)
{
// it is just an example ;)
for (int i = 0; i < 7; ++i)
{
a1 += 2;
s2 += 3;
a3 += a1 + a2;
}
}
void MyClass::f1()
{
data.a1 = 7;
}
void MyClass::f2()
{
cout << data.a2 << endl;
}