I'm new to C++, and I have a question: Can a member of struct that's a function, be defined before the struct itself?
Like this:
void foo_t::SayHello() {
printf("Hello,World!\n");
}
struct foo_t {
void SayHello();
};
Because by using this I split struct in a foo.h and SayHello() function in a C file.
EDIT::
And then include the .c in the top of .h file. Not in end of file.
I'm sorry for don't be more specific because I new to C++ and I don't know about C++'s terms.
No. (Point)
But you might do:
class foo_t;
void say_hello(const foo_t& foo) // defined in a source
struct foo_t {
void SayHello() const { say_hello(*this); }
};
But: "And then include the .c in the top of .h file. Not in end of file." makes me shiver.
No, but you can make a function proxy:
void foo_t_SayHello() {
printf("Hello,World!\n");
}
struct foo_t {
void SayHello() { foo_t_SayHello(); }
};
A decent compiler will inline this, resulting in no overhead.
Related
I have a struct defined in an anonymous namespace. Then I also want to have a class defined which has a field of that struct type.
I forward declare the struct in the header file:
struct my_str;
class my_class {
public:
struct my_str *field;
void method();
};
and then in the cpp file I have the actual type defined and some methods using it:
namespace {
struct my_str {
int data;
};
}
void helper(struct my_str * obj) {
std::cout << obj->data;
}
void my_class::method() {
helper(field);
}
This doesn't compile:
test.cc:10:20: error: reference to ‘my_str’ is ambiguous
It lists 2 definitions for my_str, the forward declaration and the one from the anonymous namespace.
Is there a way to disambiguate and make this compile?
An anonymous namespace hides the name from the outside, so you can't use that - there is no way for an outsider to refer to that type.
You don't need to write the definition in an anonymous namespace - it is hidden outside anyway.
However, this will lead to undefined behaviour if you have another global type with the same name, due to the One Definition Rule.
Probably the best solution is to hide the definition inside my_class instead:
Header:
class my_class {
public:
// Note the separate declaration; a one-liner would declare
// that there is a global `my_str`.
struct my_str; // Not defined for the outside world, but the name is accessible.
my_str *field;
void method();
};
Source:
struct my_class::my_str
{
int data;
};
namespace
{
void helper(my_data::my_str* obj) {
std::cout << obj->data;
}
}
void my_class::method() {
helper(field);
}
I came up with this approach and would like to hear what people think.
"every problem in computer science can be solved by adding another level of indirection"
.h:
struct my_str_wrap;
class my_class {
public:
struct my_str_wrap* field;
void method();
};
.cc:
namespace {
struct my_str {
int data;
};
}
struct my_str_wrap {
struct my_str w;
};
void helper(struct my_str& obj) {
std::cout << obj.data;
}
void my_class::method() {
helper(field->w);
}
I wonder what is the better practice to call a static function(and variables) inside a class or struct between A and B.
A: ClassName::functionName();
B: functionName();
Here's my simple example code:
In header file,
typedef struct _mystruct
{
static void myfunction();
} t_mystruct;
And in CPP file,
void t_mystruct::myfunction()
{
//do something
}
Now, in the same CPP file, what is the better practice to call this static function between A and B?
A: t_mystruct::myfunction();
B: myfunction();
Calling straight myfunction(); is only feasible if you are inside t_mystruct's implementation. In which case you can do according to your preferred coding style:
// .h
struct t_mystruct // You can declare it directly that way
{
static void myfunction();
void myOtherFunction();
};
// .cpp
void t_mystruct::myOtherFunction()
{
myfunction(); // That's fine!
t_mystruct::myfunction(); // That's fine too!
}
Otherwise, you have to explicitely use its fully qualified name:
void anywhereElse()
{
t_mystruct::myfunction(); // Mandatory
myfunction(); // Does not compile
}
This is true for your whole codebase, not only for the considered .cpp file.
I am going through some code which is a little un-organized.
I would like to use a class created in a cpp file used as an argument type in its header file. I know the class needs to be defined in the header but I am currently looking for a short approach here for now. This is what I have
filename: foo.cpp
class bar {
}
Now the header
filename: foo.h
class teacher {
public:
void dosomething(bar b) { ///<-----Incomplete type.
b.work(); ///
}
}
I tried declaring a prototype inside the header this way
class foo;
class teacher {
public:
void dosomething(bar b) {
b.work(); ///Error no method work for incomplete type.
}
}
What would be the simplest way to fix this issue apart from moving the bar class to the header file
You can forward-declare the type bar in the header assuming you do nothing that relies on it being a complete type. For example, this won't work:
// foo.hpp
class bar;
class teacher {
public:
void dosomething(bar b) {
// Will fail, bar is not complete:
b.work();
}
};
But this will:
// foo.hpp
class bar;
class teacher {
public:
void dosomething(bar b);
};
// foo.cpp
class bar {
public:
void work() {}
};
void teacher::dosomething(bar b) {
b.work();
}
However, I would advise instead to create a bar.hpp file with the definition of the bar type and #include it into foo.hpp.
Consider, for example, that any code (other than foo.cpp) that includes foo.hpp will be unable to invoke teacher::dosomething(bar), since it won't have any definition for bar.
I think it will be better like this :
File : bar.hh
class bar
{
...
}
File : foo.hh
#include "bar.hh"
class teacher
{
public:
void dosomething(bar b)
{
b.work();
}
}
I've been always avoiding the following in C++ (which I believe is C++03 used in VS 2008) but now I'm curious if it's possible to do this? Let me explain it with the code.
//Definitions.h header file
//INFO: This header file is included before CMyClass definition because
// in contains struct definitions used in that class
struct MY_STRUCT{
void MyMethod()
{
//How can I call this static method?
int result = CMyClass::StaticMethod();
}
};
then:
//myclass.h header file
#include "Definitions.h"
class CMyClass
{
public:
static int StaticMethod();
private:
MY_STRUCT myStruct;
};
and:
//myclass.cpp implementation file
int CMyClass::StaticMethod()
{
//Do work
return 1;
}
In this case, you would need to move the implementation of MY_STRUCT::MyMethod outside the header file, and put it somewhere else. That way you can include Definitions.h without already having CMyClass declared.
So your Definitions.h would change to:
struct MY_STRUCT{
void MyMethod();
};
and then elsewhere:
void MY_STRUCT::MyMethod()
{
int result = CMyClass::StaticMethod();
}
So I have a class:
class MyClass
public:
printSomeStuff() { //Including implementation here to save space
print(data);
}
private:
int data;
And a main program, with a template function defined outside:
template<typename T>
void print(T val) {
cout << val;
}
int main() {
MyClass a;
a.printSomeStuff();
}
The idea is that I could move MyClass somewhere else and be fine, but a new print function would need to be defined based on the scenario. Typically this would just be a cout.
If I try to actually use this style of coding, though, I get an error because print is not defined in MyClass.cpp.
How should I address this issue?
You should move your print() function into a header (and a suitable namespace) and include it into the translation units where it is needed, e.g.:
// print.h
#ifndef INCLUDED_PRINT
#define INCLUDED_PRINT
#include <iostream>
namespace utilities {
template <typename T>
void print(T const& val) {
std::cout << val;
}
}
#endif
You'd then include this header into the translation where it is used, e.g.
// MyClass.h
#ifndef INCLUDED_MYCLASS
#define INCLUDED_MYCLASS
#include "print.h"
class MyClass
public:
printSomeStuff() { //Including implementation here to save space
utilities::print(data);
}
private:
int data;
};
#endif
Put your template definition in its own header file and include it in your class implementation file.
That said, with something as trivial as printing, it may be must as easy to do it in the printSomeStuff method entirely. The extra indirection isn't really buying you anything.
The header in which print template is defined has to be accessible from the header in which MyClass is defined, but not necessarily from main, so you could move it to a separated header and include it from MyClass.hpp or even MyClass.cc