If I have a class definition
class myClass
{
void x();
};
void myClass::x()
{
hello(); // error: ‘hello’ was not declared in this scope
}
void hello()
{
cout << "Hello\n" << endl;
}
How can I call a function defined outside the scope of a class and located in the same file ? I know that I can use Namespace::function but I am not sure in this case what I should use for Namespace
You must at least declare it (if not define it) before its use.
Usually, this is done in an anonymous namespace if the function's functionality is only used in that translation unit:
class myClass
{
void x();
};
namespace
{
void hello()
{
cout << "Hello\n" << endl;
}
}
void myClass::x()
{
hello(); // error: ‘hello’ was not declared in this scope
}
This gives the function internal linkage (similar to declaring it static) and is only available in that TU.
Define the hello function in the file ahead of where it's being used - before method x - or supply a function prototype ahead of where it's being used:
void hello(); // function definition is later in the file
void myClass::x()
{
hello();
}
Related
Say I have a class as follows in a header file:
class A {
public:
void foo();
}
The function foo needs to call another "helper" function named bar. Bar isn't needed anywhere else other than inside foo. Should it be defined statically outside the scope of A:
(source file)
static void bar() { ... }
void A::foo() {
bar(); ...
}
or within the class?
(header)
class A {
public:
void foo();
private:
void bar();
}
(souce)
void A::bar() { ... }
void A::foo() {
bar(); ...
}
Bar isn't needed anywhere else other than inside foo.
If so then bar should be a private member function of class A - there is no need to define bar in global namespace.
static void bar() { ... } // not needed
instead use:
void A::bar() { ... } // <- bar should be private member function
Generally, you should only allow access to the internals of a class when necessary. Placing the function outside the class and restricting its scope--either as a static function or within an anonymous namespace, would be best. That way, you're not polluting the global namespace and you're not allowing unnecessary access to class internals.
For example, you can, in the class's cpp file, have:
namespace {
void bar() {.....}
}
and that helper function is then available for your class methods in the same cpp file.
Static functions in the cpp file would also have file scope only, but I find the static keyword to be confusing when used that way.
This code does not compile:
class A;
void foo(A&) {
}
class A {
void foo() {
foo(*this); ///This does not compile
}
};
Errors:
error: no matching function for call to 'A::foo(A&)'
foo(*this);
^
note: candidate is:
note: void A::foo()
This can be solved by calling ::foo(*this);
However, let's consider the case we are in a namespace:
namespace bar {
class A;
void foo(A&) {
}
class A {
void foo() {
foo(*this); ///This does not compile
}
};
}
Is there any other way than calling explicitly bar::foo(*this);? I mean, is there any way to look up names in the next surrounding declarative region, i.e. the containing bar namespace?
The use case is similar to what seen here.
I mean, is there any way to look up names in the next surrounding declarative region,
i.e. the containing bar namespace?
No.
You can sort of do it the other way around:
void foo() {
using bar::foo;
foo(*this); /// OK now
}
Not within the method itself. However, you can do this in the .cpp file:
namespace bar {
namespace {
auto outerFoo = foo;
}
void A::foo() {
outerFoo(*this);
}
}
Note that the name outerFoo is a hidden implementation detail which cannot cause name collisions (since it's in an anonymous namespace).
I want to only have 2 extern C functions, which are how to interact with the API. Then inside the static .lib I want to have my class that does all the work. But it shouldnt be visible to the outside.
I can do it with just pure C functions by declaring them static inside a compilation unit, but how do I do it with a class ?
If I understand your question well:
you want to create a static library presenting only two functions to the outside world
but the internals of this library should be based on a class you want to hide from outside world.
you know how to do hiding internals in classic c (i.e. using auxiliary static functions and static variables) but you don't see how to do with classes
If this is the case, the trick is simply to use an unamed namespace:
In your library source you would have something like this:
namespace { // anonymous
class U { // class visible only to the library
public:
int y;
U() :y(0) { cout << "U\n"; }
void mrun() { y++; }
};
}
void f() {
U x;
...
}
You may then use your library from outsilde world:
extern void f(); // declare the function (in a header)
f(); // invoke the function
Even if the auxiliary class would be declared in the outside world:
class U { public: int y; U(); void mrun(); };
It would not be able to used and linking errors would be generated if it would be tempted to use U. This is because unnamed namespaces are unique to each compilation unit.
If you use the same kind of solution but without the anonymous namespace, the auxiliary class would be visible and the link would succeed.
Perhaps you could mirror the class's API using C functions a bit like this:
class Cpp
{
int i = 0;
public:
int get_i() { return i; }
void set_i(int i) { this->i = i; }
};
// C code has a void* as a handle to access
// the correct instance of CPP
extern "C" void* new_Cpp()
{
return new Cpp;
}
extern "C" void delete_Cpp(void* cpp)
{
delete reinterpret_cast<Cpp*>(cpp);
}
extern "C" int Cpp_get_i(void* cpp)
{
return reinterpret_cast<Cpp*>(cpp)->get_i();
}
extern "C" void Cpp_set_i(void* cpp, int i)
{
return reinterpret_cast<Cpp*>(cpp)->set_i(i);
}
I am trying to call another function, foo(), in the Raw class from main.cpp but I keep on getting this error and I do not understand what is wrong with my code. I am working in C++, and I am using the QT framework. I am new to this language and framework.
Error:
LNK2019: unresolved external symbol "public:void __thiscall RAW::foo(void)" (?foo#Raw##QAEXXZ) referenced in function_main. File not found:main.obj
main.cpp
#include "raw.h"
using namespace std;
int main(int, char*)
{
Raw newRaw;
newRaw.foo();
return 0;
}
raw.cpp
#include "raw.h"
#include <iostream>
using namespace std;
void foo()
{
cout << "hi\n";
}
Raw::Raw()
{
cout << "raw\n";
}
raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo();
};
#endif // RAW_H
In raw.cpp you have to define foo like this:
void Raw::foo()
{
cout << "hi\n";
}
You have to put Raw:: so that the compiler knows that this is the class member function foo and not some other independent function.
As Mihai was saying, you can also define it in the Header file (.h/.hpp), but that is considered bad practice if your class method is complex in any way.
class Raw {
public:
void foo() {
cout << "hi\n";
}
};
Only time you should really ever do this is for extremely simple classes and for methods that are nothing more than getters really.
You should understand the difference between defining and declaring something in C++.
Declaring is to simply make a prototype, for example void doSomething(int); is a valid declaration as it says that the method doSomething takes an int and returns void.
Now, you need to describe what it does. This is the definition when you do void doSomething(int val) { cout << val << endl; } as you are now describing what to do with that function.
You can make the definition in the header file, as I showed, or in the source file (.c/.cpp) as Mihai showed (which is best practice). You can only make your declarations in the Header file, though.
Ok, this are some alternatives:
//raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo(){cout << "raw\n";}
};
or
//raw.h
#ifndef RAW_H
#define RAW_H
class Raw
{
public:
Raw();
void foo();
};
Raw::Raw()
{
cout << "raw\n";
}
In both cases you won't need the implementation in raw.cpp anymore. But as I said before, my first solution is standard c++ practice.
When defining a function signature in an anonymous namespace within a .hpp, is it valid to place the implementation of that function within the .cpp? When I do so I get an undefined reference error.
Example:
//hpp
#ifndef __BAR_HPP_
#define __BAR_HPP_
namespace foo
{
namespace
{
struct Bar
{
void func();
};
}
}
#endif
//cpp
using foo;
void Bar::func()
{
//...
}
Think of this:
namespace foo
{
struct Bar
{
void func();
};
}
void Bar::func() { /*impl...*/ }
Your code doesn't work for the same reason this code doesn't -- the definition is being provided in the wrong scope. What's needed is:
void foo::Bar::func() { /*impl...*/ }
But what do you put in place of foo:: to refer to the name of an anonymous namespace? It doesn't have one.
Bottom line: it's not possible to declare something inside of an anonymous namespace then define it elsewhere, as no mechanism exists for specifying the proper scope.