I am stubbing the class "myClass" and its 50+ members "myMemberFunction*" for a unit test.
I don't want to write the class name every time, so I tried the following:
namespace myNamespace{
myClass::myClass()
{
// constructor code
}
namespace myClass {
void myMemberFunction1()
{
// function 1 code
}
void myMemberFunction2()
{
// function 2 code
}
}
}
When compiling I get the error "myClass has already been declared in the current scope". However, the following works:
namespace myNamespace{
myClass::myClass()
{
// constructor code
}
void myClass::myMemberFunction1()
{
// function 1 code
}
}
Is there a way I do not have to write "myClass::" before every function stub?
How am I misunderstanding namespaces?
Classes and namespaces are two different things. You cant use namespace myClass and define all the members inside. You have to use <return type> myClass::<function> every time you define it outside the class.
You could use tools like Visual Assist, Intellisense to create the function definitions for you. But apart from that, you cannot use classes like namespaces. Another alternative is to define the functions inside the class body itself. This might be problematic each time you edit the class because then all the source files which use your class header file will get recompiled.
References: MSDN documentation
Related
When I have a C++ class MyClass in namespace mynamespace, I implement its methods as
void mynamespace::MyClass::method() { … }
I can wrap that in a namespace to shorten individual definitions to
namespace mynamespace {
void MyClass::method() { ... }
}
Is there a way to avoid having to retype MyClass:: as well so I can copy everything before the { to the header as a prototype more easily whenever the signature changes, without having to remove the MyClass:: every time?
I thought "a class is also a namespace, maybe I can do"
namespace mynamespace::MyClass {
void method() { ... }
}
but that complains that I was re-defining MyClass as a different thing. using mynamespace::MyClass; also didn't work (but would be bad anyway because how would I declare a standalone function anywhere below that line in that file if it worked).
Is there a solution to this, or is it simply not possible in C++?
No, the qualified class name must appear on any class member defined outside the class definition. (And there can only be one class definition, which is normally in a header file.)
The C++ Standard spells out this rule in [class.mfct]/4:
If the definition of a member function is lexically outside its class definition, the member function name shall be qualified by its class name using the :: operator.
and similarly in [class.static.data]/2 for static data members.
You might abbreviate this qualification using preprocessor macros, but that would seriously harm legibility and is not a common practice.
There is no idiomatic way to avoid this. Even if you or someone else might come up with a "hack" (macro-based, for example), it would make the code less readable for everyone. The normal and expected way to write C++ is for the member functions to have the preceding MyClass:: when defined outside the class definition.
I would suggest to look for a tool that can update signatures between header and source file on command.
Or, as the comments suggest, provide the definitions of your functions right with the declaration inside the class definition (i.e. provide inline definitions). But that has its own disadvantages.
Using C++20 modules, you can implement a class in one file:
module myproject.mymodule;
namespace mynamespace {
export struct my_class {
auto my_method() -> int {
return 8;
}
};
}
Or export a whole namespace fragment:
export namespace mynamespace {
struct my_class {
auto my_method() -> int {
return 8;
}
};
auto also_exported() -> void {
// ...
}
}
Then, instead of including it, you can import that module:
import myproject.mymodule;
auto frob() -> void {
auto my_instance = mynamespace::my_class{};
}
I'm fairly stupid when it comes to C++ as I'm from a pure Java background with good Python knowledge, but I am trying to make a simple C++ class with a vector referenced in the header file, and access it in a function in the source file. I can access it fine in the constructor, however as soon as I use a function, it apparently doesn't exist according to Eclipse CDT, and the build chain.
Header file (simulator.h):
#ifndef GAME_PHYSICS_SIMULATOR_H_
#define GAME_PHYSICS_SIMULATOR_H_
#include <vector>
#include "../world/object.h"
class simulator {
public:
simulator();
virtual ~simulator();
void add_object(object o);
private:
std::vector<object> objects;
};
#endif /* GAME_PHYSICS_SIMULATOR_H_ */
Source file (simulator.cpp):
#include "simulator.h"
simulator::simulator() {
object o;
objects.push_back(o); // Works fine in terms of acknowledging the existence of 'objects'.
}
simulator::~simulator() {}
void add_object(object o) {
objects.push_back(o); // Immediately throws error saying 'objects' doesn't exist.
}
The funny thing is though, is that I can access things like int's or std::string's fine. As soon as I try to use the vector it breaks. Any ideas?
Use simulator::add_object since it's a class method, just like you did for the constructor and destructor already.
Compared to Java you can define functions outside of the class definition (like in an extra .cpp file, which is usually encouraged to do so), in this case you have to prepend class_name:: to the function signature.
If not, because your function is not in the class namespace, it becomes a non-member function (meaning a function which belongs to no class) and it does not know the objects member which is inside your simulator class.
I am curious to know why following isn't allowed in C++?
1st program:
#include <iostream>
class Test {
public:
int myfun();
}
virtual int Test::myfun()
{ return 0; }
int main()
{ }
[Error] 'virtual' outside class declaration
2nd program:
#include <iostream>
class Test {
public:
int myfun();
};
static int myfun() {
std::cout<<"This program contains an error\n";
return 0;
}
int main() {
Test::myfun();
return 0;
}
[Error] cannot call member function 'int Test::myfun()' without object
So, my questions are
Why can't I make a member function virtual like as in 1st program?
Why can't I make a member function static like as in 2nd program?
Is there any reason to not allow these 2 keywords outside the class?
The modifiers must be on the function declarations, otherwise it would be impossible to call the functions given just the declarations.
Since they must be on the declarations, it would be redundant to put them on the definitions as well. There's no particularly good reason to disallow them (as long as they match the declaration), but no particularly good reason to allow them either.
virtual has to do with polymorphy and that is why it's only allowed inside a class. static is allowed outside of classes and makes global functions "private". The problem with your program is, is that myfun() in the class Test is not static and you have to create a instance of Test to invoke this method.
int main()
{
Test test;
test.myfun(); // works
return 0;
}
the static version of myfun() has nothing to do with the class and cannot be invoked like that: Test::myfunc() (because, as i said, it has nothing to do with Test). You can invoke it like this:
int main()
{
myfun(); // global function, has nothing to do with any classes
return 0;
}
You want to make a function virtual by stating this outside of class declaration. However, think of other code that will be using your class. You will most probably #include only the header of your Test class, which will contain only the class Test block, not the implementation. So while compiling that code the compiler will not know that a function is virtual. However, it needs to know, because it needs to generate different call code for virtual and non-virtual functions.
In more details, assume a more advanced program than your example. Following to your proposition, it will contain several compilation units and be organized, for example, as follows (#ifdef guards omitted for clarity):
// Test.h
class Test {
public:
int myfun();
};
// Test.cpp
#include "Test.h"
virtual int Test::myfunc() { return 0;}
// other.cpp
int foo(Test& test) { return test.myfunc(); } // <--- *
You will be compiling Test.cpp separately from other.cpp. So when you compile other.cpp, how would the compiler know that it should perform a virtual call to test.myfunc() in foo()?
The same reasoning applies to static functions. However, note that the static keyword has also another meaning that can be used outside of a class declaration.
The compiler compiles one source file ("translation unit") at a time. If you would declare a class
#include "Test.h"
class SpecialTest : public Test {
int myfun();
};
the compiler only sees what is in "Test.h", not what is in "Test.cpp". So if you were allowed to make myfun() virtual in the .cpp file only, the compiler could not correctly compile "SpecialTest" without having to look at "Test.cpp"
As indicated by juanchopanza in the comments, virtual only makes sense in the context ob classes. Recall that a virtual method is a function without an implementation, leaving this to other classes that inherit from the class where the virtual method is defined. But if the virtual definition is outside of a class, how to express inheritance in this case? It would be a non-implemented function without the possibility for other classes to actually implement it.
For static, you are confusing its meaning outside and inside the context of a class. If you want to have a function that can be called without the need for a corresponding object, you can define it as a static function of the class. If you want this function to be outside the class, simply omit the static as the function is available without the need for an object anyway. But static outside of the class context means something completely different.
I am working on a codebase that is not my own, that has the following layout:
object.h:
// Objects are defined
// #include "tickets.h" (functions to access the objects)
// An access-handler object is defined
I want to introduce a class that knows about the objects, can be accessed from functions in tickets.h, but can also use the access-handler object. The functions are separate, i.e. class functions that are called in tickets.h do not use the access-handler (I wouldn't know where to start if that weren't the case).
Therefore my class needs to be defined before tickets.h, but some of its functions need to be defined after the access-handler. Is there a way to do this without splitting it up into two header files something like the following:
// Objects are defined
// -- include declaration of class, and definition of functions that tickets.h needs
// #include "tickets.h"
// An access-handler object is defined
// -- include functions of class that need the access-handler
This seems very messy splitting things up like this into two separate files, I was hoping to keep everything contained.
Thanks for any help, I clearly only have a very rudimentary understanding of declarations/definitions in c++.
EDIT: If I use forward declaration and include it before tickets.h (with the class declared in mynewclass.h and functions defined in mynewclass.cc) will mynewclass.cc be able to use objects declared after the inclusion of mynewclass.h? Namely the access-handler object.
EDIT2: Something like this:
object.h:
class obj { // definition }
#include "tickets.h"
class obj_handler {
public void handle { // code }
}
tickets.h:
void do_something(obj o){
communicator.foo();
}
My object (communicator):
class communicator {
public:
void foo() { // code }
void bar() { // use handle() from obj_handler }
}
As you can see, my communicator needs to be used in tickets.h, but can't be defined until after obj_handler. So where should I include it?
If I correctly understand your question - you can use forward declaration to solve this problem. This will allow you to declare some class before defining it's methods. For example:
// this is forward declaration of class A, no definition provided
class A;
class B
{
// uses A
A * a_;
};
// class A definition
class A
{
// may use class B now
B * b_;
};
I'm not quite sure whether I understand this right and don't have enough reputation here yet to make this a comment, so let me try to answer your question this way, please feel free to follow up if I'm guessing wrong:
I believe what you are referring to is an entire class definition, i.e., one including all function definitions within the class declaration. Other than that, it is not very common to see object definitions followed by preprocessor directives. What is typical though is a forward declaration of functions and a class prototype.
So, for example, you could declare in some header.h:
class C
{
public:
void method1(void);
int method2(void);
};
And in some implementation.cpp the definition of the functions like:
void C::method1(void) { /*...*/ }
In the other file preceded in the inclusion chain by your access-handler you then define the other function:
int C::method2(void) { /*...*/ }
What do you mean by access-handler, by the way?
Oh, and your linker likely will yell somewhat at you if you do function definition in a header file.
With regard to your addenda: everywhere you put a forward declaration, loosely speaking, the compiler will insert a copy of the declaration in question, consider it a soft link in the context of file systems. There are negative implications associated with it, like increased duration and the memory load of compilation if you have many forward declarations of the function signature or class. It's impossible to tell whether this will word in your particular situation since only you know the actual code in question. But most likely it would work.
Take a look at these pages:
http://en.wikipedia.org/wiki/Forward_declaration
When can I use a forward declaration?
I was wondering if there is a way to put objects of a class in a header?
For example:
class MyClass {
} object;
If I made an object there and then include the header in more than one source file, I get an error of multiply defined symbols found. I am new so don't understand fully everything.
Also, I want to do something like object.function() inside of a different function which is a member of a different class how can I do that?
Assuming you want a single object, in the header file just declare the object:
extern blabla object;
and then in one source file define it:
blabla object;
As for calling a method on an object from a different class, that is perfectly fine as long as the method is public.
class foo
{
public:
void public_method();
private:
void private_method();
};
void some_other_class::method(foo &f)
{
f.public_method(); // this is fine
f.private_method(); // this is not okay, private_method can only be called from
// within foo
}
There's also a third visibility (protected), which comes into play once you start dealing with inheritance.
You can find ways to do it (see the other answers), but just don't do it. As you said, you are new to C++, so better learn the good practices, and when you need global objects - create them in the source (cpp) file.
Besides it, try to avoid using global objects at all, and define your objects inside the classes or functions.
It's not a good practice to put definitions in header files as this would result to the error you encountered. Although there are ways to get around this (extern, header guard), it should be avoided as much as possible. Just remember, put declarations in header files, definitions in source files.
About your second question note you can also call a static method using the :: operator and the class name (without an instance) :
void AnOtherClass::method()
{
TheFirstClass::static_method();
}
You could also make a use of the singleton pattern, if that fits your need in this case.
For your second question. You can always make a class object as a (private) member variable of the class you want to call object.function() from.
For example:
// File a.h, includeguards etc. left out for clarity
class A {
public:
void func();
};
// File b.h
#include "a.h"
class B {
public:
void func();
private:
A object;
};
// File b.c
#include "b.h"
void B::func()
{
object.func();
}
Hope that helps.