I'm new to C++ and get a beginner's mistake:
myclass.cpp: In function ‘int main()’:
myclass.cpp: 14:16: error: ‘func’ was not declared in this scope
This is the code:
#include <iostream>
using namespace std;
class MyClass{
public:
int func(int);
};
int MyClass::func(int a){
return a*2;
}
int main(){
cout << func(3);
}
I hope you can help me.
int main(){
cout << func(3);
}
func is not a global function; it is a member function of the class. You need an instance of the class to access it.
For example:
int main()
{
MyClass obj;
std::cout<< obj.func(3);
}
func is a member function, so it must be invoked through an object. For example:
int main()
{
MyClass obj;
std::cout << obj.func(3); // 6
}
In your example, you treated it as a free function, so the compiler looked for a function with that name. Since it could not find it, it issued a compiler error.
func is a member function of MyClass. To call it, you need an object of MyClass type to invoke it on:
int main(){
MyClass m; // Create a MyClass object
cout << m.func(3);
}
Alternatively, you could make func a static member function, which means that it is not associated with any particular instance of the class. However, you would still need to qualify its name as belonging to the MyClass class:
class MyClass{
public:
static int func(int);
};
int MyClass::func(int a){
return a*2;
}
int main(){
cout << MyClass::func(3);
}
Related
I'm beginning to learn C++. In the IDE codeblocks, this compiles:
#include <iostream>
using namespace std;
struct A {};
struct B {
A a;
}
void hi() {
cout << "hi" << endl;
}
int main() {
hi();
return 0;
}
But this doesn't:
struct B {
A a;
}
struct A {};
int main() {
hi();
return 0;
}
void hi() {
cout << "hi" << endl;
}
It gives me the errors:
error: 'A' does not name a type
error: 'hi' was not declared in this scope
Should class/function order matter in C++? I thought it doesn't. Please clarify the issue.
Yes, you must at least declare the class/function before you use/call it, even if the actual definition does not come until afterwards.
That is why you often declare the classes/functions in header files, then #include them at the top of your cpp file. Then you can use the classes/functions in any order, since they have already been effectively declared.
Note in your case you could have done this. (working example)
void hi(); // This function is now declared
struct A; // This type is now declared
struct B {
A* a; // we can now have a pointer to it
};
int main() {
hi();
return 0;
}
void hi() { // Even though the definition is afterwards
cout << "hi" << endl;
}
struct A {}; // now A has a definition
The following code compiles without any warning or error:
#include <iostream>
using namespace std;
class demo_class
{
int x;
float y;
public:
void fun(void);
};
void fun2(void)
{
cout<<"i am fun2\n";
}
void demo_class::fun(void)
{
cout<<"i am fun\n";
cout<<"i can call fun2\n";
fun2();
}
int main()
{
demo_class ob1;
ob1.fun();
return 0;
}
I am not understanding that as the scope of fun function is only in demo_class
then how can it call fun2 function, should not it show error as the access of fun function only within the demo_class?
Name lookup would try to examine all the possible scopes, until it finds at least one at any scope, then the name lookup stops.
In this case, the name fun2 can't be found at class scope, then the further scope, i.e. globle scope is examined and ::fun2 is found.
There is no reason to disallow calling a free function from within a member function. If this was the case classes would be rather useless (they would be a way to prevent code reuse instead of supporting it).
As mentioned in a comment, in cout<<"i am fun2\n"; you are calling a non-member function and calling fun is not much different from that.
Further, with a grain of salt your example is not much different from
#include <iostream>
using namespace std;
class demo_class
{
};
void fun2(void)
{
cout<<"i am fun2\n";
}
void fun3(demo_class& dc)
{
cout<<"i am fun\n";
cout<<"i can call fun2\n";
fun2();
}
int main()
{
demo_class ob1;
fun3(ob1);
return 0;
}
A member function can always be transformed into a free function. If fun would access private members we would have to declare it as friend to make the above work, but otherwise no problem here.
You can also do the reverse and call member functions in free functions as in
struct foo {
void bar(){}
};
void func(foo& f) {
f.bar();
}
int main() {
foo f;
func(f);
}
in c++, whats the difference between writing something like
myclass myobject();
//and
myclass myobject;
also i'm new to stack overflow so if i'm doing something wrong just tell me.
When you write:
myclass myobject();
You may think you're creating a new object of type myclass, but you actually declared a function called myobject, that takes no parameters, and has a return-type of myclass.
If you want to see that for sure, check this code:
#include <stdio.h>
#include <iostream>
using namespace std;
class myclass
{ public: int ReturnFive() { return 5; } };
int main(void) {
myclass myObjectA;
myclass myObjectB(); // Does NOT declare an object
cout << myObjectA.ReturnFive() << endl; // Uses ObjectA
cout << myObjectB.ReturnFive() << endl; // Causes a compiler error!
return 0;
}
prog.cpp: In function ‘int main()’:
prog.cpp:18:23: error: request for member ‘ReturnFive’ in ‘myObjectB’, which is of non-class type ‘myclass()’
cout << myObjectB.ReturnFive() << endl;
^~~~~~~~~~
The difference is same as,
int a; and int a();
I am pretty sure that you understand now. Just for the sake of answer, I am explaining it below.
int a; // -> a is a variable of type int
int a(); // -> a is a function returning int with void paramters
In the example below I do
MyClass a ();
I've been told that a is actually a function that returns a MyClass but neither of the following lines work.
MyClass b = a();
a.a = 1;
So what is a and what can I do with it?
#include "stdafx.h"
#include "iostream"
using namespace std;
class MyClass {
public:
int a;
};
int _tmain(int argc, _TCHAR* argv[])
{
MyClass a ();
// a is a function? what does that mean? what can i do with a?
int exit; cin >> exit;
return 0;
}
I've been told that a is actually a function that returns a MyClass [...]
That is a function declaration. It just declares a function called a and makes the compiler aware of its existence and its signature (in this case, the function takes no arguments and returns an object of type MyClass). This means you may provide the definition of that function later on:
#include "iostream"
using namespace std;
class MyClass {
public:
int a;
};
int _tmain()
{
MyClass a (); // This *declares* a function called "a" that takes no
// arguments and returns an object of type MyClass...
MyClass b = a(); // This is all right, as long as a definition for
// function a() is provided. Otherwise, the linker
// will issue an undefined reference error.
int exit; cin >> exit;
return 0;
}
MyClass a() // ...and here is the definition of that function
{
return MyClass();
}
#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
The above code has a class B inside a class A, and class A has a method taunt that takes a function as an argument. class B's getMsg is passed into taunt...The above code generated the following error message: "error: no matching function for call to 'A::taunt()'"
What's causing the error message in the above code? Am I missing something?
Update:
#include <iostream>
using namespace std;
class B
{
public:
int getMsg(int i)
{
return i + 1;
}
};
class A
{
B b;
public:
void run()
{
taunt(b.getMsg);
}
void taunt(int (B::*msg)(int))
{
cout << (*msg)(1) << endl;
}
};
int main()
{
A a;
a.run();
}
t.cpp: In member function 'void A::run()':
Line 19: error: no matching function for call to 'A::taunt()'
compilation terminated due to -Wfatal-errors.
I'm still getting the same error after changing (*msg)(int) to (B::*msg)(int)
b.getMsg is not the correct way to form a pointer to member, you need &B::getMsg.
(*msg)(1) is not the correct way to call a function through a pointer to member you need to specify an object to call the function on, e.g. (using a temporary) (B().*msg)(1).
The right way to do such things in OOP is to use interfaces so all you need to do is to define an interface and implement it in B class after that pass the pointer of instance which implements this interface to your method in class A.
class IB{
public:
virtual void doSomething()=0;
};
class B: public IB{
public:
virtual void doSomething(){...}
};
class A{
public:
void doSomethingWithB(IB* b){b->doSomething();}
};
This works in VS 2010. The output is the same on all lines:
#include <iostream>
#include <memory>
#include <functional>
using namespace std;
using namespace std::placeholders;
class A
{
public:
int foo(int a, float b)
{
return int(a*b);
}
};
int main(int argc, char* argv[])
{
A temp;
int x = 5;
float y = 3.5;
auto a = std::mem_fn(&A::foo);
cout << a(&temp, x, y) << endl;
auto b = std::bind(a, &temp, x, y);
cout << b() << endl;
auto c = std::bind(std::mem_fn(&A::foo), &temp, _1, y);
cout << c(5) << endl;
}
Basically, you use std::mem_fn to get your callable object for the member function, and then std::bind if you want to bind additional parameters, including the object pointer itself. I'm pretty sure there's a way to use std::ref to encapsulate a reference to the object too if you'd prefer that. I also included the _1 forwarding marker just for another way to specify some parameters in the bind, but not others. You could even specify everything BUT the class instance if you wanted the same parameters to everything but have it work on different objects. Up to you.
If you'd rather use boost::bind it recognizes member functions and you can just put it all on one line a bit to be a bit shorter: auto e = boost::bind(&A::foo, &temp, x, y) but obviously it's not much more to use completely std C++11 calls either.