I've tried to read the thread below about creating global variables that can be used between multiple files but it will not work.
Global Variable within Multiple Files
variable.h
extern const int variable1;
file1.h
class fileOne{
private:
fileTwo ft[variable1];
public:
//some functions...
};
file2.h
class fileTwo{
private:
//some variables
public:
//some functions
};
main.cpp
int main(){
int variable1 = 2;
fileOne fo;
}
When I run this, the compiler says the following:
error: array bound is not an integer constant before ']' token
Is it possible to declare a global variable and use it in the manner above?
Also: Is this an array? fileTwo ft[variable1]; Is fileTwo a class?
A fixed-sized array needs to have its size specified at compile-time, which means only a compile-time constant can be used. You can't use an externed variable for the size of the array, even if it is declared as const, as the compiler simply doesn't know the actual value of the variable since it is in another translation unit.
Also, in main.cpp, you can't declare the extern'ed variable as a local variable, it needs to be in global scope instead.
For what you are trying to do, there is no reason to use extern at all. Just declare variable1 with a constant value directly in variable.h, and then #include that file where needed, eg:
variable.h:
#ifndef VARIABLE_H
#define VARIABLE_H
static const int variable1 = 2;
#endif
file1.h:
#ifndef FILE1_H
#define FILE1_H
#include "file2.h"
#include "variable.h"
class fileOne{
private:
fileTwo ft[variable1];
public:
//some functions...
};
#endif
file2.h:
#ifndef FILE2_H
#define FILE2_H
class fileTwo{
private:
//some variables
public:
//some functions
};
#endif
main.cpp:
#include "file1.h"
int main(){
fileOne fo;
}
To define an array you need to specify the actual size of the array and the size must be something the compiler can turn into a constant. Since variable1 can't be turned into a constant, the compiler issues the error.
What you can do is something like the following.
file1.h
class fileOne{
private:
fileTwo ft[variable1];
public:
//some functions...
};
file2.h
class fileTwo{
private:
//some variables
public:
//some functions
};
main.cpp
static const int variable1 = 2; // const int for the size of the ft array of class fileOne
#include "file2.h" // class fileTwo definition is needed for class fileOne
#include "file1.h" // class fileOne has a dependency on class fileTwo
int main(){
fileOne fo; // define a fileOne object named fo
// do more stuff
}
Is it possible to declare a global variable and use it in the manner above?
Yes, but like Remy pointed out, you would need to move this variable to a header file that will be #included from file1.h
Also: Is this an array? fileTwo ft[variable1];
Yes, this is called a C-array. The C++ standard library also has C++ arrays (i.e. fixed size) using std::array<type, size>, which are much more convenient and safe to use, as well as containers like vector, list, etc.
If you want to use a C++ array, you can declare it this way for you case:
#include <array>
std::array ft<fileTwo, variable1>;
Related
Extreme c++ beginner here. I have a global variable i've tried placing into a separate header file, and also into the specific classes themselves. Throughout, i'm receiving a "redefinition" error.
Here are the global variables:
enum GRADE {F, D, CMINUS, C, CPLUS, BMINUS, B, BPLUS, AMINUS, A};
const int BAR = 60;
const int MAXSTUDENT = 100;
I have them being used and called upon in two separate classes, called student.cpp and course.cpp. They are contained in "global.cpp"
here is the header in student.cpp
#include "student.hpp"
#include "global.cpp"
#include <iostream>
using namespace std;
Here is the header in course.cpp
#include "course.hpp"
#include "student.cpp"
#include <iostream>
using namespace std;
No matter what combination of headers, or attempts to split the global variables into the classes they are being used by, i am getting a "redefinition" error. If i uninclude "#student.cpp" in the course.cpp section, i won't get the error, but i need the student.cpp for the course.cpp to work.
I'm way out of my element, would appreciate any help.
Create a file global.h. In that file you can declare your global variables. enum GRADE is not a variable but a type. It is important to remember that you can declare types and variables multiple times, but you can define them only once. So do not define them in the header, just declare them. If you want to use the same global variable across multiple cpp files you must declare them with external linkage.
/* File global.h */
#pragma once
extern const int BAR;
extern const int MAXSTUDENT;
This is an example student.h:
/* File student.h */
#pragma once
enum GRADE {F, D, CMINUS, C, CPLUS, BMINUS, B, BPLUS, AMINUS, A};
class Student
{
public:
Student();
virtual ~Student();
/* put more members here */
};
Here is an example course.h:
/* File course.h */
#pragma once
#include "student.h"
class Course
{
public:
Course();
virtual ~Course();
void addStudent(Student& student);
private:
std:vector<Student*> students;
}
Then you can choose one *.cpp file to define the globals.
For example you put them in student.cpp. Then you can already use them in student.cpp:
/* File student.cpp */
#include "student.h"
const int BAR = 60;
const int MAXSTUDENT = 100;
/* definition of student methods ... for example */
Student::Student()
{ }
Student::~Student()
{ }
In that case you do not include the global.h in the student.cpp file.
Also please do not #include any *.cpp files.
Put the declaration of your student class into student.h, put the definition of methods of the student class into student.cpp.
In the course.cpp just include global.h, course.h. But the student.h is already included via course.h. Then you can also use the global variable in this cpp.
/* file course.cpp */
#include "course.h"
#include "global.h"
/* definition of course methods ... for example */
Course::Course()
{ }
Course::~Course()
{ }
Course::addStudent(Student& student)
{
if(students.size() < MAXSTUDENT) {
// ......
}
}
Hope that helps you.
I have a problem when I'm using a static variable in my class constructor. I need to set two values equal to zero on the first line of initialization in the constructor, but I don't want to have them set to zero after the constructor is called again. These two values will be incremented. So after finding out about static variables I tried to use static variables in my constructor but errors showed.
So, what I want is for horPos and vertPos to be set to zero only once in the constructor and then incremented in the other function.
IOMovement.cpp:
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include "IOMovement.h"
#include "rectangle.h"
#define W_KEY 0x57
#define S_KEY 0x53
#define A_KEY 0x41
#define D_KEY 0x44
#define R_KEY 0x52
void IOMovement::IO() {
rectangle player(15, 5);
if (GetAsyncKeyState(W_KEY)) {
system("CLS");
vertPos--;
player.rectangleDrawPos(horPos, vertPos);
}
if (GetAsyncKeyState(S_KEY)) {
system("CLS");
vertPos++;
std::cout << "Working\n";
player.rectangleDrawPos(horPos, vertPos);
}
if (GetAsyncKeyState(A_KEY)) {
system("CLS");
horPos--;
player.rectangleDrawPos(horPos, vertPos);
}
if (GetAsyncKeyState(D_KEY)) {
system("CLS");
horPos++;
player.rectangleDrawPos(horPos, vertPos);
}
}
void IOMovement::IOStartup() {
//Variable decleration
vertPos = 0;
horPos = 0;
//Functions
IO();
}
IOMovement.h:
#ifndef IOMOVEMENT_H
#define IOMOVEMENT_H
class IOMovement {
static int vertPos, horPos;
void IO();
public:
void IOStartup();
};
#endif
You do not need static for this use case. When you create an object, typically you call the constructor only once.
So, if you dont declare them as static and use the constructor to initialize them in the following way:
IOMovement::IOMovement() : vertPos(0), horPos(0)
{//Your constructor logic. }
Static variables are not initialized in constructor but maybe modified. They are initialized outside the class eg:
int IOMovement::vertPos = 0, horPos = 0;
And in des/constructor you can idec/ncrement them:
IOMovement::IOMovement(){
vertPos++;
horPos++;
}
IOMovement::~IOMovement(){
vertPos--;
horPos--;
}
Actually, when you're designing a class you can define static variables (members) inside the class, but you can't initialize them inside the class, where they're defined. If you want to initialize a static class variable (member), you can do it outside the class, at the rest of the source file by this way:
IOMovement.h
#ifndef IOMOVEMENT_H
#define IOMOVEMENT_H
class IOMovement {
// Here you define IOMovement class variables.
static int vertPos, horPos;
public:
// I think, you must put this function in the
// public function memebers of the class.
void IO();
void IOStartup();
};
#endif
IOMovement.cpp
#include "IOMovement.h"
...
// Here you initialize both static variables, at the source file
// before you use them.
IOMovement::vertPos = 0;
IOMovement::horPos = 0;
...
At the constructor you only can initialize non-static class member variables.
In this page is explained better how are initialized static members
of a class in c++:
All static data is initialized to zero when the first object is
created, if no other initialization is present. We can't put it in the
class definition but it can be initialized outside the class by
redeclaring the static variable, using the scope resolution operator
:: to identify which class it belongs to.
At this answer in Stack Overflow is a example:
They can't be initialised inside the class, but they can be
initialised outside the class, in a source file:
// inside the class
class Thing {
static string RE_ANY;
static string RE_ANY_RELUCTANT;
};
// in the source file
string Thing::RE_ANY = "([^\\n]*)";
string Thing::RE_ANY_RELUCTANT = "([^\\n]*?)";
In these pages you can get more information about static member of a c++ class:
Static Members of a C++ Class
C++ initialize static variables in class?
Constructors (C++)
I want to declare the length of an array member variable using a constant static variable of the class. If I do:
// A.h
#include <array>
using namespace std;
class A {
array<int,LENGTH> internalArray;
public:
const static int LENGTH;
};
// A.cpp
#include "A.h"
constexpr int A::LENGTH{10};
There is the error in A.h: "'LENGTH' was not declared in this scope", when declaring internalArray.
I find it weird because how come a class member variable, i.e. LENGTH, is out of scope inside the class? The only workaround I found was to move the initialization from A.cpp to A.h:
// A.h
#include <array>
using namespace std;
constexpr int LENGTH{10};
class A {
array<int,LENGTH> internalArray;
public:
const static int LENGTH;
};
But as I understand, first these are two different variables: the global namespace scope LENGTH and the class scope LENGTH. Also, declaring a variable in .h (outside class A) will create an independent LENGTH object in every translation unit where the header is included.
Is there a way to specify the length of the array with a static class-scoped variable?
Try this:
#include <array>
class A {
public:
static const size_t LENGTH = 12;
private:
std::array<int,LENGTH> internalArray;
};
int main(){
A a;
}
You can declare the value of LENGTH right in your class header, no need to have it be a separate global variable or for it to live in the cpp file.
Use the size_t type, since that is what the std::array template expects.
If that public/private arrangement is bad for you, know that you can include multiple public/private indicators in the class header.
I am wondering how I can pass a dynamically allocated array of structures from the main function to a member function of a class. I don't necessarily need to change its values in the member function, just print it.
If I do it like I would with an integer array in the following code snippet, I get that MyStruct is not defined in the MyClass.h and MyClass.cpp files. (Which makes sense)
If I include main.cpp in MyClass.h I get a lot of weird errors. Another idea was prepending struct in the member function parameter, but that lead to other errors as well.
I need to declare the struct array outside of the class, not as a member, and I cannot use STL containers.
main.cpp:
#include "MyClass.h"
int main()
{
MyClass my_class;
struct MyStruct
{
int a;
int b;
};
MyStruct* struct_array = new MyStruct[4];
// Fill struct array with values...
my_class.printStructArray(struct_array);
}
MyClass.h:
#include <iostream>
class MyClass
{
// ...
void printStructArray(MyStruct* struct_array);
};
MyClass.cpp:
#include "MyClass.h"
void MyClass::printStructArray(MyStruct* struct_array)
{
std::cout << struct_array[0].a << struct_array[0].b;
// ...
}
Just move the struct definition into MyClass.h or it's own separate header file:
MyClass.h
#include <iostream>
struct MyStruct {
int a, b;
};
class MyClass {
// ...
void printStructArray(MyStruct* struct_array);
};
Using C++ (Visual Studio). I'm trying to find a solution for converting an enum to a string. I came across X Macros (http://drdobbs.com/cpp/184401387) which seems to be a reasonable solution but I'm having a hard time getting it to work inside of a class. All the examples I've seen show everything defined outside of a class.
// ColorNames.h
X(Red, "Red"),
X(Blue, "Blue"),
...
// MyClass.h
class MyClass
{
public:
MyClass();
virtual ~MyClass();
#define X(a, b) a
enum Colors {
#include "ColorNames.h"
};
#undef X
#define X(a, b) b
char *colorNameStrings_[] = {
#include "ColorNames.h"
};
#undef X
}
The IDE chokes on the line *colorNameStrings_[] =... I guess because you can't initialize a data member variable in the header file? How do I get this to work?
The problem is that you can't initialize a non static constant inside a class definition.
You would probably have to do it like that:
// MyClass.h
class MyClass
{
public:
MyClass();
virtual ~MyClass();
#define X(a, b) a
enum Colors {
#include "ColorNames.h"
};
#undef X
static const char * colorNameStrings_[];
};
And in the .cpp file:
// MyClass.cpp
#include "MyClass.h"
#define X(a, b) b
const char * MyClass::colorNameStrings_[] = {
#include "ColorNames.h"
};
#undef X
Instead of using X-Macros, consider using the Boost.Preprocessor library. The initial, one-time definition of the code generation macros takes a bit of work, but the end result is far cleaner and much easier to reuse.
I provided a basic implementation of a generic, Boost.Preprocessor-based enum-to-string-name conversion in an answer to "How to convert an enum type variable to a string?"
Use a struct like this
struct convert
{
std::map<MyEnum, std::string> mapping;
convert()
{
mapping[SOME_ENUM_VALUE] = "SomeValue";
// etc to fill map
}
std::string operator()(MyEnum enum)
{
return mapping[enum];
}
};
Then use like this:
convert c;
std::string ret = c(myenum); //calls operator()