Consider the following code:
#include <iostream>
class CTest
{
public:
CTest() : c(0)
{}
void Method1()
{
c++;
std::cout<<"c: "<<c<<std::endl;
}
private:
int c;
};
int main()
{
CTest A,B,C;
A.Method1();
B.Method1();
C.Method1();
return 0;
}
c: 1
c: 1
c: 1
for each object of this type, the c value is different. To avoid name conflict, I am interested to put the c variable inside the function since Method1 is the only place where it is supposed to be used. My concern is how to make it independent for each different object. Is there any built-in C++ solution?
#include <iostream>
class CTest
{
public:
CTest()
{}
void Method1()
{
static int c=0;
c++;
std::cout<<"c: "<<c<<std::endl;
}
private:
};
int main()
{
CTest A,B,C;
A.Method1();
B.Method1();
C.Method1();
return 0;
}
c: 1
c: 2
c: 3
You could do this with templates,
template <typename int> class CTest
{
void Method1()
{
static int c = 0;
}
};
And instantiate CTest<1> A;, CTest<2> B; etc, taking care that you use a different int each time. That way, you get a different c per <n>, which is local to Method1. But this is quite contrived, will not work if you want to instantiate CTests dynamically, and I don't think I'd use it in production.
Perhaps an approach using the pImpl idiom would be better.
If this is just a naming issue, then you can just use different names:
class CTest
{
public:
void Method1()
{
int& c = unique_but_similar_to_something_else;
c++;
std::cout << "c: " << c <<std::endl;
}
private:
int unique_but_similar_to_something_else;
};
This allows your variable to have a correct name within class scope, but a more friendly name within method scope.
class CTest
{
public:
CTest() : MY__c(0)
{
}
void Method1()
{
int& c = MY__c; // now c is of different meaning and doesn't spoil the "c" we want to have no conflicts with...
c++;
std::cout << "c: " << c << std::endl;
}
private:
int MY__c;
};
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;
}
My scenario is simplified in the following example:
#include <iostream>
#include <vector>
using namespace std;
class C;
class A
{
protected:
C * cPointer;
A();
virtual void updateList() = 0;
void callFunc();
};
class B : public A
{
private:
vector<int> list;
void updateList();
public:
void callFromA();
};
class C
{
friend class A;
friend class B; // I want to get rid off this declaration
private:
int sum;
void set_sum( int val );
public:
static C * getCPointer();
};
A::A()
{
cPointer = C::getCPointer();
}
void A::callFunc()
{
updateList();
}
void B::updateList()
{
list.push_back(2);
list.push_back(4);
int s = 0;
for( unsigned int i=0; i<list.size(); i++ )
{
s += list[i];
}
cPointer->set_sum(s);
}
void B::callFromA()
{
callFunc();
}
void C::set_sum( int val )
{
sum = val;
cout << "Sum at C is: " << sum << endl;
}
C * C::getCPointer()
{
static C cPointer;
return & cPointer;
}
int main( int argc, char ** argv)
{
B b;
b.callFromA();
return 0;
}
This example works fine. But I want to get rid of the "friend class B" declaration in class C and achieving similar functionality. Actually I want to have either of the following:
accessibility of C::set_sum() from B::updateList() which will not be possible without the "friend class B" declaration in class C.
accessibility of B::list in A::callFunc() whereby I can push the logic from B::updateList to A::callFunc() which basically means ability to access a list in the derived class from the base class. In this way, I will be able to access the set_sum() in A::callFunc() due to "friend class A" declaration in class C.
Any idea to achieve this without involving major design changes is desirable!
Thanks!
I'm not sure if I understand all your restrictions, but maybe this works better for you. Basically, you can access B::list from A using a virtual function. I've commented the changes in the code.
#include <iostream>
#include <vector>
using namespace std;
class A;
class C
{
friend class A;
private:
int sum;
void set_sum(int val);
public:
static C * getCPointer();
};
class A
{
protected:
C * cPointer;
A();
virtual int getS() = 0; // virtual function to calculate data from vector in derived class B
virtual void updateList()
{
cPointer->set_sum(getS()); // A is friend of C, so you can access B data from A
}
void callFunc();
};
class B : public A
{
private:
vector<int> list;
void updateList();
int getS() // concrete implementation to access vector data
{
int s = 0;
for (unsigned int i = 0; i < list.size(); i++)
{
s += list[i];
}
return s;
}
public:
void callFromA();
};
A::A()
{
cPointer = C::getCPointer();
}
void A::callFunc()
{
updateList();
}
void B::updateList()
{
list.push_back(2);
list.push_back(4);
A::updateList(); // Call to super implementation
}
void B::callFromA()
{
callFunc();
}
void C::set_sum(int val)
{
sum = val;
cout << "Sum at C is: " << sum << endl;
}
C * C::getCPointer()
{
static C cPointer;
return &cPointer;
}
int main(int argc, char ** argv)
{
B b;
b.callFromA();
return 0;
}
You can not access members of derived classes inside the base class, period. The object at hand might be of the base class, or even of a completely unrelated derived class, with guaranteed "interesting" consecuences. Any design asking for doing so is seriously broken, and needs rethinking.
You can make the member function of the base class which wants to do so virtual, and redefine it in the derived class to do whatever perversion you have in mind. Meanwhile, the chaste member of the base class can just refuse if called, signalling the mistake in a sane way. That way you get a guarantee that nothing too untoward can happen.
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;
...
}
In this case, there should be only one or zero instances of the static variable. It depends whether f() has been called or not.
void f()
{
static int a;
}
But how many instances of the static variable are there if f() is a method?
class A
{
void f()
{
static int a;
}
};
Same as for the function: 0 or 1. It is very easy to check too:
class A
{
public:
void f()
{
static int a = 0;
++a;
cout << a << endl;
}
};
int main()
{
A a;
a.f();
a.f();
A b;
b.f();
}
Output:
1
2
3
However, if you derieve from class A and make the function virtual like this:
class A
{
public:
virtual void f()
{
static int a = 0;
++a;
cout << a << endl;
}
};
class B:public A
{
public:
void f()
{
static int a = 0;
++a;
cout << a << endl;
}
};
then the a variable will be different for the base and for each derived class (because the functions are different too).
The same... being a member function is orthogonal to being a static local.
Please see the example code below:
class A
{
private:
class B
{
public:
foobar();
};
public:
foo();
bar();
};
Within class A & B implementation:
A::foo()
{
//do something
}
A::bar()
{
//some code
foo();
//more code
}
A::B::foobar()
{
//some code
foo(); //<<compiler doesn't like this
}
The compiler flags the call to foo() within the method foobar(). Earlier, I had foo() as private member function of class A but changed to public assuming that B's function can't see it. Of course, it didn't help. I am trying to re-use the functionality provided by A's method. Why doesn't the compiler allow this function call? As I see it, they are part of same enclosing class (A). I thought the accessibility issue for nested class meebers for enclosing class in C++ standards was resolved.
How can I achieve what I am trying to do without re-writing the same method (foo()) for B, which keeping B nested within A?
I am using VC++ compiler ver-9 (Visual Studio 2008). Thank you for your help.
foo() is a non-static member function of A and you are trying to call it without an instance.
The nested class B is a seperate class that only has some access privileges and doesn't have any special knowledge about existing instances of A.
If B needs access to an A you have to give it a reference to it, e.g.:
class A {
class B {
A& parent_;
public:
B(A& parent) : parent_(parent) {}
void foobar() { parent_.foo(); }
};
B b_;
public:
A() : b_(*this) {}
};
This is an automagic, albeit possibly nonportable trick (worked on VC++ since 6.0 though). Class B has to be a member of class A for this to work.
#ifndef OUTERCLASS
#define OUTERCLASS(className, memberName) \
reinterpret_cast<className*>(reinterpret_cast<unsigned char*>(this) - offsetof(className, memberName))
#endif
class A
{
private:
class B
{
public:
void foobar() {
A* pA = OUTERCLASS(A, m_classB);
pA->foo();
}
} m_classB;
public:
foo();
bar();
};
Basically what Georg Fritzsche said
#include <iostream>
#include <cstring>
using namespace std;
class A
{
private:
class B
{
A& parent_;
public:
//B(); //uncommenting gives error
~B();
B(A& parent) : parent_(parent) {}
void foobar()
{
parent_.foo();
cout << "A::B::foo()" <<endl;
}
const std::string& foobarstring(const std::string& test) const
{
parent_.foostring(test); cout << "A::B::foostring()" <<endl;
}
};
public:
void foo();
void bar();
const std::string& foostring(const std::string& test) const;
A();
~A(){};
B b_;
};
//A::B::B() {}; //uncommenting gives error
A::B::~B(){};
A::A():b_(*this) {}
void A::foo()
{
cout << "A::foo()" <<endl;
}
const std::string& A::foostring(const std::string& test) const
{
cout << test <<endl;
return test;
}
void A::bar()
{
//some code
cout << "A::bar()" <<endl;
foo();
//more code
}
int main(int argc, char* argv[])
{
A a;
a.b_.foobar();
a.b_.foobarstring("hello");
return 0;
}
If you uncomment the default B constructor you would get an error
If you want to reuse functionality from A then you should inherit from A not nest B inside it.
Combining Igor Zevaka's and enthusiasticgeek's answers. Also, using reinterpret_cast for calculating offset (If you create class member variable using new keyword):
#include <iostream>
#include <cstring>
using namespace std;
template < typename T, typename U > constexpr size_t offsetOf(U T:: *member)
{
return (char*) &((T*) nullptr->*member) - (char*) nullptr;
}
class A
{
private:
class B
{
public:
B(string message);
~B();
void foobar()
{
A *pA = reinterpret_cast<A*> (reinterpret_cast< unsigned char*> (this) - offsetOf(&A::b_));
pA->foo();
pA->bar();
std::cout << "DONE!";
}
};
public:
void foo();
void bar();
A();
~A() {};
B* b_ = new B("Hello World!");
};
A::A()
{
cout << "A constructor\n";
};
A::B::B(string message) {
cout << "B constructor\n";
cout << "Message = " << message << "\n";
};
A::B::~B() {};
void A::foo()
{
cout << "A::foo()" << endl;
}
void A::bar()
{
cout << "A::bar()" << endl;
foo();
}
int main(int argc, char *argv[])
{
A* a = new A();
a->b_->foobar();
return 0;
}
Output:
B constructor
Message = Hello World!
A constructor
A::foo()
A::bar()
A::foo()
DONE!
References:
https://stackoverflow.com/a/10607424/9524565
https://stackoverflow.com/a/3058382/9524565
https://stackoverflow.com/a/20141143/9524565