I want to create a utility namespace that includes a function that generates numbers following a normal distribution with specified mean and variance.
MathUtils.hpp
#include <cmath>
#include <random>
namespace MathUtils {
double genNormalDist();
extern std::random_device rd;
extern std::mt19937 gen;
extern std::normal_distribution<> normalDist;
};
MathUtils.cpp
MathUtils::gen = rd();
MathUtils::normalDist = std::normal_distribution<double>(
0, sqrt(2/(inputNumber + outputNumber)));
\\Error here: Types 'long' and 'normal_distribution' are not compatible
double MathUtils::genNormalDist() {
return normalDist(gen);
}
Other parts of the program will call MathUtils::genNormalDist(). Other parts of the program will not need to access rd, gen, or normalDist. What is the best way to implement this?
Starting to learn C++, much guidance needed. Thanks!
You don't have to declare the variables in the namespace as extern. A bit tricky to understand why, I'll try to give it a shot.
What you want is to create a new variable in the namespace. Thus, you need to define the variable (i.e. allocate memory for it) in the namespace. If you declare your variable as extern, it would basically be saying "Don't create a new variable, i'm just letting you know that this variable exists somewhere so I can use it here".
However, a better approach would be to write a small class.
Related
Is it possible to code a library with a parameter that will be defined by the user at compile time without modifying the library?
Library:
test.h
#ifndef TEST_H
#define TEST_H
#define MAX_NB USER_DEF
void myFunc();
#endif
test.cpp
#include "test.h"
int arr[MAX_NB] = {0};
void myFunc() {
for (int i = 0: i < MAX_NB; i++ ) {
// DO SOMETHING
}
}
And the main code:
#define USER_DEF 5
#include "test.h"
void main() {
while (1) {
myFunc();
}
}
I suppose I am getting an error (USER_DEF not declared in this scope) because USER_DEF is not defined in the translation unit containing test.h and test.c, but I hope there is a way to do it, but I can't find it.
My goal is to have an array with a user-defined size (code modified).
The answer is that it doesn't make sense to use variable-sized arrays for a very restricted 8-bit system with very limited RAM.
Instead you should have a fixed size array of n bytes. Let the user pick a number, then ensure that it is less or equal to n. Then keep track of the used size with a plain integer variable. You must always reserve memory for the worst case.
The array must have static storage duration, since it will be too large to be allocated on the stack.
I'd usually go and suggest to check out the templates, although, you can create user-defined variables, they are called function parameters. Please take a look
To sum it up, this is not what you call user-defined variable, because this is defined by the programmer, not by the user of the program. This is called a constant, whatsoever. If you want to create a compile-time constant, defined by you, you can take a look at constexpr.
Also, let me explain to you why this doesn't work correctly. You guessed correctly, it's because it is not defined into the header file, but why? Because headers come first and then comes the main file. The header searches for the defined constant and fails to find it, and that is the reason why you get the USER_DEF not declared in this scope.
I'm new to c++ and am trying to make calculations using two .hpp files cpScalar.hpp and cpVector.hpp as assignment. I'm having difficulty as I read through forward declarations explanations - all solutions I find say that I cannot use methods from another class in another header before "declaring class" fully, and I don't know what I have to do to "fully declare/ define" the class.
To clarify, cpVector relies on cpScalar and vice versa - circular dependency is needed
I'm planning to use of cpScalar to get array of cpScalar in cpVector, but I cannot access parameter input 'cpScalar sarr[]' because I did not declare, and am getting invalid use of incomplete type error. I want to know what I need to do for this section.
I don't intend to use pointer in place of vectors in constructors, as this leads to flexible array problem that are (seemingly) solved using 'struct' and 'malloc' which I did not learn in class.
Below is my code:
// cpVector
#ifndef CPVECTOR_HPP
#define CPVECTOR_HPP
#include <iostream>
#include <vector>
#include "cpScalar.hpp"
using namespace std;
class cpScalar;
class cpVector{
private:
vector<cpScalar> arr; // cpScalar* arr; seems to be more complicated...
unsigned int size;
public:
cpVector(cpScalar sarr[], unsigned int size2){ // this constructor is given
this->size = size2;
arr.resize(size);
for (int i =0; i<size; i++){
arr[i] = sarr[i]; // this gives incomplete type error
}
};
... more public functions...
#endif
#ifndef CPSCALAR_HPP
#define CPSCALAR_HPP
#include <iostream>
#include <string>
#include "cpVector.hpp"
using namespace std;
class cpVector;
class cpScalar{
private:
int intScalar;
double doubScalar;
public:
cpScalar(int num){
intScalar = num;
};
cpScalar(double num){
doubScalar = num;
};
If you are new in c++, forward declaration might confuse you. You need to learn how the compiler reads files and how it determines linkages between them.
If that's the whole code of your cpScalar.hpp, then you dont need to include cpVector.hpp. It's because you are not instantiating or using the class in that file.
Right now you have a circular dependency between the two classes. cpVector.hpp includes cpScalar.hpp, and then cpScalar.hpp includes cpVector.hpp. The compiler is your friend, be easy on him/her.
To clarify, cpVector relies on cpScalar and vice versa - circular dependency is needed
I see no reason to believe this. You may think a circular dependency is needed, but it's not. Think about how you learned about those concepts. You might have learned about scalars (in the form of counting things) way back before you started school. Vectors, on the other hand, tend to be a more advanced subject that built upon what you knew about scalars (in high school or maybe a few years earlier?).
The structure within a program is likely to be similar: scalars should be definable on their own, while vectors build upon scalars. When vectors and scalars interact (such as multiplying a vector by a scalar), the definition should belong to the more "advanced" class, i.e. cpVector. No circular dependency is needed.
I'm thinking about a different implementation of this part of a code:
unsigned int whyamIexisting=100000; // also good for me static unsigned ...
double rand_number_generation(){
// create random number [0,1]
static unsigned int rand_counter=0;
rand_counter++;
if( rand_counter > whyamIexisting) {
update_my_seed(time(NULL));
rand_counter=0;
}
// random number generation
return thats_your_gorgeous_numb(); // random algorithm
}
main(){
...modify whyamIexising
...use rand_number_generation() several times
...
}
Should I not use global variable? And if yes what solution will you suggest?
thanks!
If you are working with multiple functions and using a global variable, i would suggest you not to modify it and instead use local variable for storing it and then do the modification.
I usually avoid using global variables. :-)
There... gone!
double rand_number_generation(unsigned int whyamIexisting){
// create random number [0,1]
static unsigned int rand_counter=0;
rand_counter++;
if( rand_counter > whyamIexisting) {
update_my_seed(time(NULL));
rand_counter=0;
}
// random number generation
return thats_your_gorgeous_numb(); // random algorithm
}
main(){
unsigned int limit = 17;
...use rand_number_generation(limit) several times
...
}
There is no point having a global variable in your case. It only makes the program hard to maintain if it were to grow. It doesn't add anything in the example you have given.
I don't know the rest of code, so it's based on fragments you posted and may be completely wrong.
whyamIexisting is kind of a description for environment where rand_number_generation is run, but it also describes it's state, same as rand_counter.
From tags I see that you write in C++, which is an object oriented language. The thing about object orientation is that you have, you know, objects. Probably not everyone will agree with me (thinking about my High School IT teacher), but I personally consider putting everything that has it's own state into class as a good practise. Does object containing whyamIexisting as it's field, rand_counter as another and rand_number_generation as it's method (and probably getter and setter for whyamIexisting) solve your problem?
Unless you don't use whyamIexisting anywhere else in the code, because then you can simply make it local in main and pass as parameter to function rand_number_generation.
I am trying to convert an old Fortran 77 code to C++ and most of the variables are declared in Common blocks such as:
COMMON/BLK1/Gw(200),Eta(4096),t(4096),Phi(200),w(200)
COMMON/BLK2/g,dw,Vel,M,dt,N,Ioutp1,Ioutp2
COMMON/BLK3/Hs,Std,E,Hs1,Tdt
As I understand it, common blocks are used simply to make variables accessible throughout the program in different subroutines. Therefore, in a C++ program, would I be able to create structs with the variables (outside of the main) and call the variables this way as members of the struct?
Based on my understanding of COMMON from this page, the C++ equivalent would be to make a file called common.h (with include guards) that contains:
namespace BLK1
{
int const Gw = 200;
int const Eta = 4096;
int const t = 4096;
int const Phi = 200;
int const w = 200;
}
namespace BLK2
{
extern int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
extern int Hs, Std, E, Hs1, Tdt;
}
Also, in exactly one .cpp file in your project you need to provide a definition for any non-consts, e.g. in foo.cpp:
#include "common.h"
namespace BLK2
{
int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
}
namespace BLK3
{
int Hs, Std, E, Hs1, Tdt; // initialized to 0 by default
}
You may want to use a different type than int, e.g. unsigned long. I'm assuming the initialized values are meant to be const; if not then change int const to extern int and remove the initializer. The initializer would have to go in the definition in the .cpp file.
Avoid the mistake of declaring a non-const, non-extern variable in the header; this causes undefined behaviour if the header is included in two different units.
You access these variables by writing BLK1::Eta for example.
As you surmise it might be considered tidier to use a struct instead of a namespace, although you'd still have to create an instance of the struct which is declared extern in the header, and defined in exactly one .cpp file; and if you are pre-C++11 it's more annoying to provide initializers.
(Of course, even better would be to refactor the code to not use globals. But it might be useful as a first pass to do a direct translation).
Common blocks with the same name overlap each other in memory. You can allocate a chunk of memory, and typecast pointers to it. Another option is to declare them in a union. That is why a union was invented. Certainly once your union is set up, you use extern in the other modules.
Put the following into a common header and an instance of it into module 1.
Add an extern so it can be seen in module 2.
union blk1
{
struct module_1_view
{
double gw(200);
double eta(4096);
double t(4096);
double phi(200);
double w(200);
}
struct module_2_view
{
double parameters(8592); // 200 + 4096 + 4096 + 200
double w_status(200);
}
}
Imagine module 1 being responsible for loading some set of doubles from a file into the the variables in the module_1_view. Once those parameters are loaded and validated, module 2 is called, which accesses the parameters from the module 2 view. Nearly all of them are accessed via the parameters variable, except for the w_status, which is actually 200 indicators that indicate something about the success or validation of the parameters.
The key point is that module 1 and 2 access the same chunk of memory (hence the union) and they use their own set of variable names.
I can't speak directly to Fortran, but if you want to make a variable accessible throughout the entire program in c/c++, extern is the keyword you are looking for.
Extern is a C style way of sharing data. C++ would push you into OO design, of which a variable that is tightly coupled to many objects isn't good OO.
If you are trying to do C++ things on top of legacy code, sometimes static methods, which are passed pointers to your C++ class can act as wrappers. Heres a simple example of that:
extern int _magicVariable;
static void call( void* klass )
{
((MyClass*)klass)->functionCall( _magicVariable );
}
Inside MyClass, you'll need to name void call( void* ) as a friend. Now the legacy code can call(void*) with a pointer to your class, passing in the _magicVariable into your OO design. From there c++ will do its thing.
The bottom line is you have a lot of ways to accomplish the task, try to do what makes sense based on your desired code structure.
This question already has answers here:
Are global variables bad? [closed]
(28 answers)
Closed 9 years ago.
I'm not sure whether it's appropriate to ask this here. I'm concerned about the memory allocation and I don't know where to read up on that.
I'm debating with myself whether I should declare local variables per root-finding function, or just use global variables that each function can reuse per call. Please note that I don't plan on using recursion here. Just (do-)while (or for) loops only.
I'd really appreciate it if I can get sufficient explanation too.
// [1]
// global(?) variables
// functions.cpp
#include <cmath>
#include "functions.h"
using namespace std;
double guess1; // upper
double guess2; // lower
double root;
double prevGuess;
double sigFigs;
double minSigFigs;
double newt_rhap(params)
{
// do stuff
}
double bisection(params)
{
// do stuff
}
===============
// [2]
// local variables
// functions.cpp
#include <cmath>
#include "functions.h"
using namespace std;
double newt_rhap(x,y,z,f(),f_prime())
{
double guess = x;
double sigFigs = y;
double minSigFigs = z;
// do stuff
}
double false_position(w,x,y,z,a())
{
double xr;
double upper = w;
double lower = x;
double xprev;
double fxr;
double fxu;
double fxl;
double sigFigs = y;
double minSigFigs = z;
// do stuff
}
You should use globals when you want to share the value of variables between several functions and want to avoid passing the values inbetween the functions.
In other cases it is better to use local variables. With globals you need to be sure the value wasn't modified accidently somewhere.
Additionally, you might have to frequently reintialize the values before usage.
Don't use global unless you know that the variables value is going to be same for all the functions that you use are defining. But it is better to avoid globals.
Always try to avoid using Global variables unless you need some particular variable/values common or to be accessed in other functions also. Because by declaring Global variable as when your program get bigger and bigger then you will face difficulty in debugging,that is at which particular function you global variables are getting wrong values. Like you were expecting 10 but it giving 20 then you have sit and debug which function does this. That is why Java like language does not allow Global variable concept itself.