Unclear struct definition in a C++ header file - c++

I am relatively new to C++, coming from a Python background.
I have the following header file:
struct Example
{
int n_example;
float random_number;
float second_random_number;
Example(int n_example, float random_number, float second_random_number);
};
I do not get what the second to last line do (i.e, Example(int n_example, float random_number, float second_random_number); )
Might be a super silly question, but it is the first time that I encounter such syntax in C++.
Indeed, normally for struct definition I am used to something like:
struct Example
{
int n_example;
float randon_number;
float second_random_number;
};

this here
Example(int n_example, float random_number, float second_randon_number);
is the declaration of the constructor, you can call that and pass the parameters every time you want to construct a new instance of the class Example...
like
int main()
{
Example foo(0, 3.14f, 2.77f);
}
the only thing you are missing is the implementation of that constructor...
it may look like this (depending on what version of c++ you are using):
Example(int n_example, float random_number, float second_random_number) :
n_example{n_example},
random_number{random_number},
second_random_number{second_random_number},
{
...
}

The line you're questioning is a class constructor and as far as I'm aware is something equivalent to __init__ in Python. The reason it's declared in the class definition body - between {} - is because C++ is strongly typed, which means that the class definitions has to be fully specified. You cannot "add" new functionality afterwards, during a runtime of a program. Contrary to C++, Python belongs to loosely typed group of languages where you can define classes' fields and methods on the go during a runtime which makes it more flexible but more error-prone in the end.
Also be aware that this is just a simple declaration which should be included within the header file .h The definition of this constructor most of the time (unless inlined) will end up in respective .cpp file which consist of all the logic related to the class. This separation of declaration .h and definition .cpp files is one of the building blocks of the language. In the end only the .cpp files are compiled and then linked together resulting in a hopefully working application.

Related

Can you define C++ methods in a reopened class environment, rather than by prefixing with the class name?

In every lesson and book on C++ I've ever seen, a class has been written like this:
header.h
class MyClass
{
...
int myMethod(int my_para);
};
source.cpp
...
int
MyClass::myMethod(int my_para)
{
...
}
But I do find that the MyClass:: just adds to the natural chaos and bewilderment of C++, especially when MyClass is actually more like MySomethingSomethingCreator. I would like to write my class definitions in more of a namespace style, like this:
header.h
class MyClass
{
...
int myMethod(int my_para);
};
source.cpp
class MyClass
{
...
int myMethod(int my_para)
{
...
}
}
Now, I know from trying that doing exactly this does not work, but is there a way to do something similar - just to remove a little of the noise? I am not interested in defining functions actually inside the class declaration - that's the work of the devil!
but is there a way to do something similar
No.
MyClass:: just adds to the natural chaos and bewilderment of C++
It's just one of the little things that a new C++ programmer has to learn to accept. Once you get used to it, it will no longer be bewildering.
MyClass:: just adds to the natural chaos and bewilderment of C++
I wouldn't agree with you. Imagine you are working with a huge code database, and you come across a definition of a function in .cpp file like this.
.
.
.
.
int myfunc(std::string some_arg)
{
//whatever can be here
}
.
.
.
.
.
And now you would wonder, is this a function in a namespace or method of some class. Of course the class specifier you suggested would appear above, but in can be thousand of lines above, or even 10 thousands, which one probably wouldn't want to deal with. Someone would like to know if it is a method or function by directly looking on it.
The MyClass:: specifier serves greatly for this purpose.
You cannot. This is generally not a problem, though. In fact, there is good reason to want to do this with free functions. John Lakos points out in Large-Scale C++ Volume I (2020) p. 155–156, you can (and may want to) do this:
// foo.h
namespace my_product {
int foo(int);
} // namespace my_product
then
// foo.cpp
#include <my_product/foo.h>
int my_product::foo(int x) {
return x * 2;
}
The advantage of this is: suppose you want to change the signature to take float and you change it in the .cpp to float my_product::foo(float x). If done this way, float my_product::foo(float x) can only define the function, it can't declare it, so you'd get a compile error: https://godbolt.org/z/eGbv3rTx5
error: out-of-line definition of 'foo' does not match any declaration in namespace 'my_product'
float my_product::foo(float x) {
^~~
whereas if your .cpp file is
// foo.cpp
#include <my_product/foo.h>
namespace my_product {
float foo(float x) {
return x * 2;
}
} // namespace my_product
and you try to use the function, you have to wait for the whole project to build and then get a link error: https://godbolt.org/z/soo7r97fG
undefined reference to `my_product::foo(int)'
I've started to get in this habit of defining functions like this so I can have immediate compile errors rather than waiting for a potentially big build only to get a link error, which then requires fixing the header (hopefully correctly!) and then waiting again for a big rebuild.

How to reference classes/methods in one file without caring about the order of them (c++)

Is there any way to reference classes/methods in one file where the order of them wouldn't matter? My question might look weird but I will present example:
I must include all code in one source file (I know it's really unhandy) for entry so for example:
class One{
public:
float methodOne(){
return multiply(10, 20);
}
};
float multiply(float a, float b){ return a * b; }
to reference multiply I would need to move it over the method that reference it
but with more classes and methods it starts to become impossible so is there any other way to do this than moving methods over?
*edit i forgot to add the main problem that the methods are using classes which causes the mess
you can add function prototype on top of program or in header file
float multiply(float, float);
class One{
public:
float methodOne(){
return multiply(10, 20);
}
};
float multiply(float a, float b){
return a * b;
}
then you can define it anywhere(below or above class)
In a small program, I would create a header file which declares all the functions and and classes. All the functions (class methods and independent methods) can be implemented (defined) in a .cpp file in any order. Just need to include the header file in the .cpp file.
In a large project, it is better to create a pair of .h and .cpp files for each class. The independent functions can be implemented in a separate pair of .h and .cpp files.
With this approach, you wouldn't need to care about the order of function definitions. Whenever you call a function, make sure to include corresponding .h file.

Error : unknown type name 'FeatureTracks'

I had made an structure for feature tracks:
struct FeatureTracks{
std::vector<std::vector<cv::Point2f> > tracks;
std::vector<size_t> offset;
};
Then making a function to call it:
void genTrackMatrix(const std::vector<cv::Mat>& images, FeatureTracks& trackMatrix, int tWindow, int stride);
But the function calling is giving an error:unknown type name 'FeatureTracks'
Please help me out. Thanks in advance.
Well, I assume, that it is simply not defined. The struct definition must be done before the function prototype declaration. Is the struct defined within another c file? Then move it to a header file and include the Header. Is the struct definition later in the c file? Then move it to the beginning.
The C-Compiler has no global scope, it only sees the current file and processes it top-down. Just "play" being a compiler and step through the C-file. Have you seen every type definition before it is used?

Nested classes definition and initiation through files

I'm trying to make class functions I can tack on to other classes, like with nested classes. I'm still fairly new to C++, so I may not actually be trying to use nested classes, but to the best of my knowledge that's where I'm at.
Now, I've just written this in Chrome, so it has no real use, but I wanted to keep the code short.
I'm compiling on Windows 7, using Visual Studio 2015.
I have two classes in file_1.h:
#pragma once
#include "file_2.h"
class magic_beans{
public:
magic_beans();
~magic_beans();
int getTotal();
private:
double total[2]; //they have magic fractions
}
class magic_box{
public:
magic_box(); //initiate
~magic_box(); //make sure all objects have been executed
void update();
magic_beans beans; //works fine
magic_apples apples; //does not work
private:
int true_rand; //because it's magic
};
... And I have one class in file_2.h:
#pragma once
#include "file_1.h"
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}
Now, I've found that I can simply change:
magic_apples apples;
To:
class magic_apples *apples;
And in my constructor I add:
apples = new magic_apples;
And in my destructor, before you ask:
delete apples;
Why must I refer to a class defined in an external file using pointers, whereas one locally defined is fine?
Ideally I would like to be able to define magic_apples the same way I can define magic_beans. I'm not against using pointers but to keep my code fairly uniform I'm interested in finding an alternative definition method.
I have tried a few alternative defines of magic_apples within my magic_box class in file_1.h but I have been unable to get anything else to work.
You have a circular dependency, file_1.h depends on file_2.h which depends on file_1.h etc. No amount of header include guards or pragmas can solve that problem.
There are two ways of solving the problem, and one way is by using forward declarations and pointers. Pointers solve it because using a pointer you don't need a complete type.
The other way to solve it is to break the circular dependency. By looking at your structures that you show, it seems magic_apples doesn't need the magic_beans type, so you can break the circle by simply not includeing file_1.h. So file_2.h should look like
#pragma once
// Note no include file here!
class magic_apples{
public:
magic_apples();
~magic_apples();
int getTotal();
private:
double total[2];
}

Can't use a class that is defined in another hpp file

I'm having a little problem trying to use my "gameAux" class in "userAux.hpp" file I made.
Here are the two hpp files I made.
I marked the place where I get an error.
userAux.hpp:
#include "gameAux.hpp"
class userAux{
int gameId;
int userId;
int rate;
gameAux aGame; <---error: ‘gameAux’ does not name a type
};
gameAux.hpp:
#include "userAux.hpp"
class gameAux{
int gameId;
userAux aUser; <--- OK
};
I'll be very happy if someone could point out what's the problem :)
You cannot have one class include an instance of another class, and have that other class include an instance of the first class. That's an infinite recursion and obviously cannot work.
The answer is to use pointers and forward declarations.
class gameAux; // forward declaration
class userAux{
int gameId;
int userId;
int rate;
gameAux* aGame;
};
class gameAux{
int gameId;
userAux* aUser;
};
When two classes depend on each other like this I would be tempted to place them both in the same header file. However if you want separate header files then you could forward declare each class in the other classes header file. That way neither header file needs to include the other.
Your problem is that both of your classes depend on each other. When the compiler goes to see how much space it needs to reserve for gameAux objects, it says 'ok, I need an int and a userAux to fit in there'. So the next question is, how much space does it need for ints and userAux objects?
Then when it tries to figure out how much space it needs for a userAux object, it says 'ok, three ints and a gameAux object'... and there's the problem. It's going to keep going back and forth between those two files, trying to figure out how much space it needs for each thing, and never be able to figure it out.
To solve this, you need to make one of your classes depend on a reference or pointer to the other class. Since references and pointers always take up the same amount of space on a given system, the compiler will be able to allocate space for a userAux if it sees this:
class gameAux;
class userAux{
int gameId;
int userId;
int rate;
gameAux &aGame; // or gameAux *aGame; // <---error: ‘gameAux’ does not name a type
};
and then it will have a fine time allocating space for both of the objects, no problems ^^
EDIT: Also, you won't need to #include the header file for gameAux any more at the top of userAux.hpp - just forward-declare gameAux like so at the top of the file: class gameAux.
You don't need to include the entire class definition. You can avoid a circular dependency by just forward declaring, and using a pointer:
#include "gameAux.hpp"
class gameAux; // forward declaration
class userAux{
int gameId;
int userId;
int rate;
gameAux *aGame;
};
and vice versa in the other file. Then #include the appropriate hpp header in the implementation source file for each class.