I am having a lot of troubles with my C++ code but I can't understand why.
I am developing a static library libmylib.a that contains myclass.h and myclass.cpp.
The problem I am having is like this:
// myclass.h
class myClass{
public:
myclass();
myclass(a,b);
// some methods.
private:
int a ;
int b ;
};
In myclass.cpp I define the constructors methods etc etc and everything works fine:
I am able to use the library in my main.cpp code.
I then added a friend function:
// myclass.h
class myClass{
public:
myclass();
myclass(a,b);
friend void foo() ;
// some methods.
private:
int a ;
int b ;
};
I define the foo function in myclass.cpp like this
// myclass.cpp
void foo(){
cout << "In foo function " ;
}
The problem is that if I try to use foo() in main.cpp I get a compile error that states:
//main.cpp
#include "myclass.h" // foo() is declared here!
foo() ;
main.cpp:62:6: error: ‘foo’ was not declared in this scope
Now I really can't understand where the problem is.
I notice that after adding the friend function it seems that the linker doesn't use mylib anymore, but I can't understand why. Moreover it is strange, because if I comment foo() in main.cpp myclass and its methods can be used without problems.
What am I doing wrong? I spent two hours trying to figure out, but really can't understand!!!
Solution: following the advice in the answer:
// myclass.h
void foo() ; // the function has to be declared outside the class
class myClass{
public:
myclass();
myclass(a,b);
friend void foo() ; // but here you have to specify that
// is a friend of the class!
// some methods.
private:
int a ;
int b ;
};
This is not a linker error, it is a compiler error. The compiler is telling you that it does not know how to call function foo, because it lacks its definition or declaration.
Declaring a function as a friend is no substitute for a proper declaration. When you say foo is a friend, you do not also introduce foo into a scope. In a sense, friendship declaration is a private detail of your class invisible from the outside.
In order to use a function in C++ you need to declare it first. This is usually done through a header file corresponding to the implementation file, but you can do it simply like this:
void foo();
If foo is defined in the same file as main, you can move foo ahead of the main to fix the problem (seeing a function definition prior to first use is OK with the compiler).
Have you declared foo before using it:
#include "header_where_foo_is_declared.h"
int main()
{
foo();
}
or
void foo();
int main()
{
foo();
}
???
Related
I'm currently working on a project that has several classes, and at times, I have to call functions from other classes to make things work. I want to know if the way I'm doing it is efficient, or if there is another way I should be doing this. Here's an example
class FirstClass{ // FirstClass.cpp
public:
void aFunction(){
std::cout << "Hello!";
}
private:
}
Let's say I wanted to call aFunction in another class, I'd do this:
#include "FirstClass.cpp"
class SecondClass{ //SecondClass.cpp
public:
FirstClass getFirstClass;
// I would then use getFirstClass.aFunction();
// whenever I want to call.
private:
}
I don't feel like this is very productive. Is there a better way of doing this?
First of all why including source file FirstClass.cpp?
The proper way is to create a header file FirstClass.h and a source file FirstClass.cpp and include the header inside the source and in main.cpp.
Second: A member function is a member function it is a member of an object so you need an instance of that class to call its member. If you don't want to instantiate the class then declare the member function as a static function then you can either call it using an object or directly using class name followed by scope operator: FirstClass::aFunction().
// FirstClass.h
class FirstClass{ // FirstClass.cpp
public:
void aFunction();
}
// FirstClass.cpp
#include "FirstClass.h"
void FirstClass::aFunction(){
std::cout << "Hello!";
}
// SecondClass.h
#include "FirstClass.h"
class SecondClass{
public:
void foo();
private:
FirstClass getFirstClass;
};
// SecondClass.cpp
void SecondClass::foo()
{
getFirstClass.aFunction();
}
To make it a static:
struct A
{
static void do_it(){std::cout << "A::do_it()\n";}
};
struct B
{
void call_it(){ A::do_it();}
};
There's nothing with "productivity" to whether have a static or non-static data/function member.
The semi-colon is not redundant at the end of class body so you need t add them: class FirstClass{ }; class SecondClass{};.
I am new at C++ language and I am trying to understand why the next thing is happening:
I have a header file header.h
namespace myNamespace{
class myClass{
public:
myClass();
~myClass();
void myFunction(void);
}
void myVoid();
}
The definitions are in header.cpp
using namespace myNamespace;
void myClass::myFunction(void){
//DO anything
}
void myVoid(){
//Do anything
}
And in the main.cpp I have the follow:
#include "header.h"
main(){
myVoid();
myNamespace::myVoid();
}
Why If I try to call myFunction of the class myClass from the main I have a successful compile, and if I try to call the function as in the main file I have an undefined reference error? I can fix it if in the header.h moves myVoid out of the namespace.
Why is this happening? I am trying to figure out how this works.
Thanks in advice,
If you don't specify definition of myVoid (I mean just declaring it like you did), then the compiler can never be sure if you are implementing the function which is declared in namespace or just defining a new one.
On the other hand, if you are defining myClass::myFunction, it has to be the method that is declared in the defined class.
To make it clear, investigate the following code and take a look here (very similar question)
namespace Test {
int myVoid(void); // declaration
class yourClas; // declaration
class myClass{ // definition
public:
myClass();
~myClass();
void myFunction(void); // declaration which belongs to defined class
}
}
void myVoid() {
// definition, but compiler can't be sure this is the function
// that you mention in the namespace or a new function declaration.
}
void myClass::myFunction(void){
// absolutely definition for the method of the corresponding class
}
Single File Example
Here is a simple program using namespaces.
#include <iostream>
namespace foo {
void hello();
}
void foo::hello() {
std::cout << "hello\n";
}
void foo::hello(); // Why is this syntax allowed? When is it useful?
int main() {
foo::hello();
}
This program compiles fine and produces the expected output.
$ ./a.out
hello
I want to know when is the void foo::hello(); declaration useful? In this program, clearly this declaration is redundant. But since this syntax exists, this must be useful in some other scenario?
Two-File Example
Here is an example that shows that the void foo::hello(); declaration standing alone is useless.
// foo.cpp
#include <iostream>
namespace foo {
void hello();
}
void foo::hello() {
std::cout << "foo::hello\n";
}
// main.cpp
void foo::hello(); // This does not work!
int main()
{
foo::hello();
}
Trying to compile the above two files leads to the following errors:
$ clang++ foo.cpp main.cpp
main.cpp:1:6: error: use of undeclared identifier 'foo'
void foo::hello();
^
main.cpp:5:5: error: use of undeclared identifier 'foo'
foo::hello();
^
2 errors generated.
The only way to fix main.cpp in the above example seems to be include the namespace declaration:
// main.cpp - fixed
namespace foo {
void hello();
}
void foo::hello(); // But now this is redundant again!
int main()
{
foo::hello();
}
So after we get this code to compile properly, the void foo::hello(); declaration seems redundant again. Is there any scenario where such a declaration would be playing a useful role?
In most cases in C++, for anything that can be either declared without defining it or can be completely defined, a declaration or a definition of that thing can appear in all the same contexts. So this is probably just a way of keeping the pattern consistent.
The C++ Standard does not go out of its way to forbid things that are a logical consequence of its other rules but just not useful, as long as it's reasonably clear what will happen if someone does it anyway. If it did add these restrictions, that would put extra work on compiler writers for no real benefit.
From [basic.def]/1
A declaration may introduce one or more names into a translation unit or redeclare names introduced by previous declarations. If so, the declaration specifies the interpretation and attributes of these names.
Which allows code like this
#include <iostream>
void foo();
void foo();
void foo();
void foo();
void foo();
int main()
{
foo();
}
void foo() { std::cout << "foo()"; }
To be valid. There is no harm in having multiple declarations of a function, as long as we have only one definition, it won't cause an issue.
Another example would be you have a global function you want to be a friend of multiple classes. You would include that function prototype in each class header so you can friend it and then you would include all of those class headers in your main source file. So
A.h
void foo();
struct A { friend void foo(); }
B.h
void foo();
struct B { friend void foo(); }
main.cpp
#include "A.h"
#include "B.h"
...
and that would be converted to
main.cpp
void foo();
struct A { friend void foo(); }
void foo();
struct B { friend void foo(); }
...
So we would want this to be legal.
class Example{
public:
friend void Clone::f(Example);
Example(){
x = 10;
}
private:
int x;
};
class Clone{
public:
void f(Example ex){
std::cout << ex.x;
}
};
When I write f as a normal function, the program compiles successful. However, when I write f as a class member, this error occurs.
Screenshot:
The error you're seeing is not a root-cause compilation error. It is an artifact of a different problem. You're friending to a member function of a class the compiler has no earthly clue even exists yet,much less exists with that specific member.
A friend declaration of a non-member function has the advantage where it also acts as a prototype declaration. Such is not the case for a member function. The compiler must know that (a) the class exists, and (b) the member exists.
Compiling your original code (I use clang++ v3.6), the following errors are actually reported:
main.cpp:6:17: Use of undeclared identifier 'Clone'
main.cpp:17:25: 'x' is a private member of 'Example'
The former is a direct cause of the latter. But doing this instead:
#include <iostream>
#include <string>
class Example;
class Clone
{
public:
void f(Example);
};
class Example
{
public:
friend void Clone::f(Example);
Example()
{
x = 10;
}
private:
int x;
};
void Clone::f(Example ex)
{
std::cout << ex.x;
};
int main()
{
Clone c;
Example e;
c.f(e);
}
Output
10
This does the following:
Forward declares Example
Declares Clone, but does not implement Clone::f (yet)
Declares Example, thereby making x known to the compiler.
Friends Clone::f to Example
Implements Clone::f
At each stage we provide what the compiler needs to continue on.
Best of luck.
Im trying to do a C++ class function that can return other classes values. The code works if class A is defined first but i have more code that i dont want to mangle around. I figured i need somekind of forward declaration for class A.
What kind of forward declaration do i need to get this work? All my code is in one file. Does this problem dissapear if i properly split my classes to multiple files and include them to project or does it make any difference to VC++ compiler?
Semi pseudo code below.
// forward declaration
class A;
// class deifinitions
class B {
private:
int testvalue;
public:
void settestvalue(A &Aobj);
}
void B::settestvalue(A &Aobj) {
testvalue = Aobj.settestvalue();
}
class A {
private:
int test = 10;
public:
int testvalue();
};
int A::testvalue() {
return test;
}
// mainloop
A Aobj;
B Bobj;
Bobj.settestvalue (Aobj);
just put the defination of B's member-function after A's class definition.