#include <iostream>
#include <cstring>
using namespace std;
class Obj;
class Test {
friend class Obj;
public:
Test()
{
}
~Test()
{
}
void foo()
{
//print();
//Obj::print();
//Obj x;
//x.print();
}
};
class Obj {
public:
void print()
{
cout << "print here" << endl;
}
};
int main()
{
Test test;
test.foo();
return 0;
}
Quick question,how can I call print the correct way in Test::foo() ?
You need to define the member function after the definition of Obj:
class Test {
public:
void foo();
};
class Obj {
public:
void print() { }
};
void Test::foo() {
Obj o;
o.print();
}
As mentioned by james you should define the member function after the definition of Obj. Also you are calling Obj::print, but print is not a static member function so you must call it on an instance of Obj not Obj itself.
If you really do want print to be a static member, declare it so.
class Obj {
public:
static void print(){ blah }
}
Also you do not need to make Obj a friend in order to access its public methods.
Also can OP please define "correct way", I was assuming you wanted it to be a static member function, james' answer is correct if you want one instance of Obj per instance of Test.
UPDATED
OP, as per your comment you must have the declaration of Obj along with print BEFORE using it within Test. This can be achieved in many ways:
move the entire class Obj defintion (and declaration) before Test
declare Obj's methods with its class definition and define them later.
declare Test like you have and Define Test as per James' post (after Obj).
The following works fine:
#include <iostream>
#include <cstring>
using namespace std;
class Obj {
public:
static void print()
{
cout << "print here" << endl;
}
};
class Test {
public:
Test()
{
}
~Test()
{
}
void foo()
{
Obj::print();
}
};
int main()
{
Test test;
test.foo();
return 0;
}
However it is always nicer (in my opinion) to separate declaration from definition for all but the most trivial of cases.
Related
I write c++ with c++11 and have a question as title.
Ex.
class Hi {
public:
Hi(){};
test() {cout << "test" << endl;};
}
void noop(){
; // noop
};
int main(){
Hi hi();
hi.test = noop; // just example, not real case
return 0;
}
Is that possible to replace test() of class Hi to a noop function in runtime!? Thanks.
You can't replace any function at runtime, whether class member or not.
However, you can achieve the desired effect by using a variable.
(This is yet another example of the "add a level of indirection" method of solving problems.)
Example:
class Hi {
public:
Hi(): test([this]() { do_test(); }) {}
std::function<void()> test;
void do_test() { cout << "test" << endl; }
};
void noop(){}
int main(){
Hi hi;
hi.test(); // Outputs 'test'
hi.test = noop;
hi.test(); // Does nothing
}
You have to think object oriented. In this case you have to elevate your function to be an object we can name it MethodClass then your function in the class Hi will be a pointer to that class. Below a simple example
#include <memory>
class BaseMethodClass
{
public:
virtual void method() = 0;
};
class MethodClass1 : public BaseMethodClass
{
public:
virtual void method()
{
// your implementation here
}
};
class MethodClass2 : public BaseMethodClass
{
public:
virtual void method()
{
// your implementation here
}
};
class Hi
{
public:
Hi() { method = nullptr; };
void setMethod(BaseMethodClass* m) { method.reset(m); }
void test() { if (method) method->method(); };
private:
std::shared_ptr<BaseMethodClass> method;
};
int main()
{
Hi hi;
hi.setMethod(new MethodClass1());
hi.test();
hi.setMethod(new MethodClass2());
hi.test();
return 0;
}
This way you can override your methos as you want not just noop
I have two class, class A, Class B, in class B has a static function like below:
class A {
public:
void method(){ B::method(); }
};
class B {
public:
static int method() {
cout << "method of b" << endl;
}
};
int main()
{
class A a;
a.method();
}
this code build error, because in class A, B is not be declared, but I want class A be defined earlier than class B, how should i do? I was thought it may need forward declaration, but it seems not this reason...
Take a look at the modified code. Inline comments explain the changes:
class A {
public:
// only declare the method
void method();
// Do NOT define it here:
// { B::method(); }
};
class B {
public:
static int method() {
std::cout << "method of b" << std::endl;
return 0;
}
};
// and now, as B implementation is visible, you can use it.
// To do this, you can define the previously declared method:
void A::method() { B::method(); }
int main()
{
class A a;
a.method();
}
Hint: Please never use using namespace std
I have a program:
#include <iostream>
using namespace std;
class A {
public:
virtual void Output() {
cout << "A";
}
};
class B :public A {
public:
A::Output();
void Output() {
cout << " B ";
}
};
int main() {
A* a = new B;
a->Output();
return 0;
}
I don't understand why the line "A::outPut()" has an error. Please help me with this question.
When used in a method of a subclass of A, the A::Output() is an expression calling the Output method from the A class. As any other executable expression, it can only be use inside a method and not in the class body. Because the class body should only contain declarations (and definitions). For example, you cannot call functions at a class body level.
Ok so I have a bit of a silly question but I think it might be useful if there was a way to do it.
Anyway, assume I have the following class:
class Foo
{
public:
virtual void Show() = 0;
};
What if I want to use Foo without inherriting? Is there a way to simply do the following (rather than create a whole new class to implement Show):
Foo F;
F.Show = [&]{/*Do something here*/}; //Assign some function or Lambda to Foo instance F
Is there a way to do that? I know it seems silly but I just have to know if that or something similar can be done.
It obviously doesn't compile :l
Is there a way to do that?
No, you can't instantiate Foo if it has a pure virtual member function.
I just have to know if that or something similar can be done.
It depends what you mean by similar. If you forget about the pure virtual, you can give Foo::Show() an implementation in terms of, say, an std::function<void()>, which you can set from a lambda expression, another std::function<void()> or any callable entity with that signature and return type.
#include <functional>
class Foo
{
public:
virtual void Show() { fun(); }
std::function<void()> fun;
};
Then
#include <iostream>
int main()
{
Foo f;
f.fun = []{std::cout << "Hello, World!";};
f.Show();
}
Note as suggested in #MrUniverse's comment, you should check whether the function has been assinged before calling it. This can be easily done:
virtual void Show() { if (fun) fun(); };
Something like that can work :
#include <functional>
#include <iostream>
class Foo
{
public:
std::function<void(void)> Show;
};
int main()
{
Foo f;
f.Show = [&] () { std::cout << "Hello !" << std::endl; };
f.Show();
}
Pure virtual classes can not be instantiated at all
The closest you can get is a local anonymous class:
#include <iostream>
class Foo
{
public:
virtual void Show() = 0;
};
int main() {
struct : Foo {
void Show() {
std::cout << "Hello world\n";
}
} f;
f.Show();
}
You can instead store a function pointer called show in the class.
class Foo
{
public:
void (*Show)();
Foo()
{
Show = 0;
}
}
Then if Show != 0 you can call it (aka if the user assigns a function pointer to it).
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;
...
}