Ok, I reduced my problem to something that looks really silly but I simply cannot understand why this:
#include <iostream>
class ABC{
public:
void Print() { std::cout<<"ABC_TEST!\n"; }
};
int main(){
Print();
return 0;
}
Gives me: error: identifier "Print" is undefined
Thanks in advance!
It should be like this :
#include <iostream>
class ABC{
public:
void Print() { std::cout<<"ABC_TEST!\n"; }
};
int main(){
ABC abc;
abc.Print();
return 0;
}
You need to create an object of type ABC before you can call instance methods(or member functions which are not static)
Alternatively, Print() can be a static function and you will be able to call it with the :: operator.
class ABC {
public:
static void Print() { std::cout << "ABC_TEST\n"; }
};
int main()
{
ABC::Print();
return 0;
}
Above all else, Print() can also be a global function:
void Print()
{
std::cout << "ABC_TEST\n" ;
}
int main()
{
Print();
return 0;
}
Print() is a member function of ABC, so you can only call it on an instance of ABC:
ABC abc;
abc.Print();
As a completely unrelated note, in C++ a return with value 0 is implied, so it is not necessary to write return 0.
Print() is a member function of your ABC class, you need an object to invoke it on:
int main()
{
ABC abc; // This creates an instance of ABC
abc.Print();
// ^^^^
// This invokes member function `Print()` on the object abc.
return 0;
}
The address of abc will be passed as an implicit first parameter to function Print(): that parameter will be accessible inside of Print() (more generally, inside an invoked member function) as the this pointer.
If you try calling Print() as if it were a non-member, free function, no implicit this pointer would be passed, and it makes sense that the compiler complains about it.
If you want to be able to invoke Print() the way you did, you should make it a non-member function:
void Print() { std::cout<<"ABC_TEST!\n"; }
int main()
{
Print(); // This is fine now!
}
Related
I'm testing, trying to call a member function being passed as a parameter,
the member function has to be one of another class.
this is an example, which gives an error:
"pointer-to-member selection class types are incompatible ("B" and
"A")"
This is the code, what am I doing wrong?
#include <iostream>
using namespace std;
class A {
private:
public:
void fA(int x) {
cout << "hello" << endl;
}
void fB(int x) {
cout << "good bye" << endl;
}
A() {
}
};
class B {
private:
void (A:: * f)(int) = NULL;
public:
B(void (A:: * f)(int)) {
this->f = f;
}
void call() {
(this->*f)(10); //What's wrong here?
}
};
A a = A();
B b = B(&(a.fA));
B b2 = B(&(a.fB));
int main(void) {
b.call();
b2.call();
}
&(a.fA) is not legal C++ syntax. &A::fA is. As you can see, there is no object of type A anywhere of this syntax. &A::fA is just a pointer to a member function, not a pointer-to-member-together-with-an-object combo.
Now in order to call that pointer-to-member, you need an object of class A. In class B, you don't have any. You need to get one in there somehow, and call the function this way:
(a->*f)(10);
where a is a pointer to that object of class A.
I have a C-style function, which stores another function as an argument. I also have an object, which stores a method that must be passed to the aforementioned function. I built an example, to simulate the desired situation:
#include <functional>
#include <iostream>
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
std::function<void(int)> f;
void foo(int i) {
std::cout << i << "\n";
}
};
int main() {
TestClass t;
t.f = std::bind(&TestClass::foo, &t, std::placeholders::_1);
foo( t.f.target<void(int)>() );
return 0;
}
What is expected is that it will be shown on screen "2". But I'm having trouble compiling the code, getting the following message on the compiler:
error: const_cast to 'void *(*)(int)', which is not a reference, pointer-to-object, or pointer-to-data-member
return const_cast<_Functor*>(__func);
As I understand the use of "target", it should return a pointer in the format void () (int), related to the desired function through std :: bind. Why didn't the compiler understand it that way, and if it is not possible to use "target" to apply what I want, what would be the alternatives? I don't necessarily need to use std :: function, but I do need the method to be non-static.
This is a dirty little hack but should work
void foo(void(*f)(int)) {
f(2);
}
class TestClass {
public:
void foo(int i) {
std::cout << i << "\n";
}
};
static TestClass* global_variable_hack = nullptr;
void hacky_function(int x) {
global_variable_hack->foo(x);
}
int main() {
TestClass t;
global_variable_hack = &t;
foo(hacky_function);
return 0;
}
//can also be done with a lambda without the global stuff
int main() {
static TestClass t;
auto func = [](int x) {
t->foo(x); //does not need to be captured as it is static
};
foo(func); //non-capturing lambas are implicitly convertible to free functions
}
Why are we able to call the showA() method without object? But if I use void A::showA(A& x) in the method definition then I have to call it using A's object, why?
#include <iostream>
class A {
public:
int a;
A() { a = 0; }
void showA(A&);
};
void showA(A& x)
{
std::cout << "A::a=" << x.a;
}
int main()
{
A a;
showA(a);
return 0;
}
Why are we able to call the showA() method without object?
You don't call the member function A::showA, but instead the free function showA. In fact, the member function A::showA(A&) is declared, but never defined, only the free function showA(A&) has a definition.
If you want to call A::showA, you need a definition;
void A::showA(A& x) { /* ... */ }
// ^^^ this makes it a member function definition
and then call it as
A a;
a.showA(a);
(Note that it doesn't make much sense to pass the a instance to A::showA invoked on the identical a instance, but that's another issue).
This function
void showA(A& x)
{
std::cout << "A::a=" << x.a;
}
is not a member function of the class A.
It accepts one argument of the type A &.
As for the member function showA then it is declared but not defined.
You could declare it within the class like
class A {
public:
int a;
A() { a = 0; }
void showA() const;
};
and then define it outside the class definition like
void A::showA() const
{
std::cout << "A::a=" << a;
}
In this case the function main can look like
int main()
{
A a;
showA(a);
a.showA();
return 0;
}
You can't call it because showA(the one you are thinking) is not the part of the class.It is a global function.The showA function which you declared in class was never defined. In order to do so modify your code a bit.
Change this piece of code.
void A::showA(const A& x) {
std::cout << "A::a=" << x.a; } // It is advised to make const as it doesn't change state.
class foo{
public:
int n;
private:
virtual void sayHi(){
cout<<"Hi there!";
}
};
How do I get the address of sayHi()??
main(){
foo f;
typedef void(*fptr)();
fptr func = reinterpret_cast<fptr>((&f)[0]);
(*func)();
}
The code above didn't work.
I know that the first 8 bytes of "f" object is a pointer to a virtual table where it contains the pointers to the functions, I'm using 64-bits machine. I'm basically trying to call the sayHi() through its pointer rather than calling it directly from f, since sayHi() is private anyway! How would I do this? Am I apportioning it right??
You cannot simply have a pointer to a non-static member function and call it without an object. The most straight-forward way to interpret your question would be using a pointer-to-member as in:
auto fptr = &foo::sayHi;
foo f;
(f.*fptr)();
Now, you say you want to call it without having to go through f. It's not clear exactly what this means. Using a lambda is probably good enough to create a callable that works as you want
auto func = [] { return foo{}.sayHi(); };
func(); // call
or using a specific object and capturing it by reference (shown) or by value
foo f;
auto func = [&f] { return f.sayHi(); };
func();
sayHi() is a non-static method of a class. You need to use a pointer-to-method instead of a raw pointer (the implementation of a method pointer is compiler-specific, so assuming the internal layout of the pointer-to-method is not portable).
Also, sayHi() is private to foo, so main() cannot access it directly. You need to either:
declare sayHi() as public:
class foo
{
int n;
public:
virtual void sayHi(){
cout << "Hi there!";
}
};
int main()
{
typedef void (foo::*fptr)();
fptr func = &foo::sayHi;
foo f;
(f.*func)();
return 0;
}
make main() be a friend of foo:
class foo
{
int n;
virtual void sayHi(){
cout << "Hi there!";
}
friend int main();
};
int main()
{
typedef void (foo::*fptr)();
fptr func = &foo::sayHi;
foo f;
(f.*func)();
return 0;
}
Well, ISO C++ forbids taking the address of a bound member function to form a pointer to member function. However, you can do something like this, if it helps. You may check the result here.
#include <iostream>
using namespace std;
class foo{
int n;
public:
virtual void sayHi(){
cout<<"Hi there!";
}
};
typedef void(*fptr)();
int main() {
auto func = reinterpret_cast<fptr>(&foo::sayHi);
(*func)();
return 0;
}
Really bad title, couldn't think of how to word it, sorry.
So say I had the following code:
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
int getSize() {
return 32;
}
}
void doStuff(A a) {
std::cout << a.getSize() << std::endl;
}
int main() {
B b;
doStuff(b);
}
It would print out 0, however I want it to print out 32. In other words, I want to pass it the class and it prints out that classes function, so I could create a class C, where the size is 64, and if I pass that C instance to the doStuff function, I want it to print 64.
Is there any way I can do this in C++, would I have to use templates or some fancy C++ feature I don't know about?
A one-byte patch:
void doStuff(A &a) {
std::cout << a.getSize() << std::endl;
}
Your version takes the argument by value, which means that the function makes a copy of b (a copy which is an A) and then calls the copy's getSize(). In this version, the function takes the argument by reference, and calls b's own getSize(), which is B::getSize().
You should use pointers, or even better: smart pointers! That way, the function of the runtime type gets called. It's a basic example of polymorhpism. If you want to avoid pointers, Beta's slicing approach is equally valid.
#include <iostream>
#include <memory>
class A {
virtual int getSize() {
return 0;
}
}
class B : public A {
virtual int getSize() {
return 32;
}
}
void doStuff(std::shared_ptr<A> a) {
std::cout << a->getSize() << std::endl;
}
int main() {
std::shared_ptr<A> b(new B());
doStuff(b); // Will output '32'.
}
This should correctly call the function as implemented by B.
Slicing the object is one approach, and in addition I think you're asking for, I think, a pretty straightforward use of polymorphism in C++. http://www.cplusplus.com/doc/tutorial/polymorphism/
That's almost immediately applicable, just call your class A Shape, and B and C could be Square and Triangle. Your DoStuff function could take a pointer to a Shape, then you can pass it a triangle or a square, and when you deference the Shape in the function, it will call the correct function.
So you'd have (also you need to make the members public, I think):
class A {
public:
virtual int getSize() {
return 0;
}
};
class B : public A {
public:
int getSize() {
return 32;
}
};
void doStuff(A* a) {
std::cout << a->getSize() << std::endl;
}
int main() {
B b;
doStuff(&b);
}