How do I access a constant defined in a header file? - c++

The following is my .h
#ifndef GRID_H_
#define GRID_H_
#include <array>
namespace game{
class Grid{
public:
static const int dimension = 10;
std::array<int, dimension*dimension> grid;
Grid();
int get_cell(int x, int y);
};
}
#endif /* GRID_H_ */
The following is my .cpp
#include "Grid.h"
namespace game {
Grid::Grid() {
// TODO Auto-generated constructor stub
}
int get_cell(int i, int j){
return (std::get<(i*dimension+j)>grid);
}
}
Compiler says:
error: 'dimension' was not declared in this scope.
I tried to add the scope resolution operator game::, but it didn't work. How can I access this constant from the header file?
Shouldn't it be a global public variable?! And the include should copy and paste the code from the header file. I don;t understand what's wrong. Sorry for the basic question; I'm new to C++/

You have to use the class name to access a static member:
int Grid::get_cell(int i, int j){
return (std::get<(i* Grid::dimension +j)>grid);
}
Note: :: operator refers to global scope. But dimension is in class scope, not global.
Your usage of std::get is wrong. It should be
return (std::get< /*a constant value*/>(grid)); //

int get_cell(int i, int j){
return (std::get<(i*dimension+j)>grid);
}
This defines a global function, you could should refer to dimension directly:
int get_cell(int i, int j){
return (std::get<(i* Grid::dimension+j) > grid);
// ^^^^^^
}
You should define get_cell as a member of Grid
int Grid::get_cell(int i, int j){
// ^^^^
return (std::get<(i*dimension+j)>grid);
}

Related

Not all of my constructors are being imported?

I'm making a heap class to be importable with heap.h and my constructors including bool types do not work, yet every other constructor and function imported works.
Here is what's in heap.h:
#ifndef __HEAP_INCLUDED__
#define __HEAP_INCLUDED__
#include <iostream>
#include <vector>
using namespace std;
class heap{
int capacity;
bool isMinHeap; //1 is min heap -- ascending order
vector<int> * content;
public:
heap();
heap(bool t);
heap(vector<int> * input);
heap(vector<int> * input, bool t);
void print();
void prettyPrint();
int parent(int i);
int leftChild(int i);
int rightChild(int i);
int size();
int getMax();
void insert(int data);
void heapifyDown(int index);
void heapifyUp(int index);
int invalidChild(int index);
int deleteMax();
int deleteMin();
bool minDir();
int at(int index);
};
vector<int> * heapSort(vector<int> * input);
void swap(vector<int> * vec, int a, int b);
#endif
Here are the defined constructors in heap.cpp. Note, all constructors work fine when I add a main to this file to test stuff:
class heap{
vector<int> * content;
int capacity = 256;
bool isMinHeap; //1 is min heap -- ascending order
public:
heap(){
content = new vector<int>;
isMinHeap = 0;
}
heap(bool t){
content = new vector<int>;
isMinHeap = t;
}
heap(vector<int> * input){
content = input;
isMinHeap = true;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
heap(vector<int> * input, bool t){
content = input;
isMinHeap = t;
for(int i = content->size()/2; i >= 0; i--){
heapifyDown(i);
}
}
//other functions below
}
The constructors with bool do not work in main.cpp, which has #include "heap.h" at the top. The files are all in the same directory and I am compiling with this command: g++ heap.cpp main.cpp -o main. Why do two of my constructors not work?
The error I see is
/usr/bin/ld: /tmp/ccwomODk.o: in function `main':
main.cpp:(.text+0x4e2): undefined reference to `heap::heap(bool)'
collect2: error: ld returned 1 exit status
-Wall does not elaborate on the issue. I'm pretty sure the issue is with my linking somewhere because the constructors work inside of heap.cpp when I use them in there.
What you are doing with the class in the .cpp file is wrong. You are not allowed to define the class twice. There must only be one class heap { /*...*/ }; in the program (but it may be included in multiple .cpp files). Otherwise the one-definition-rule (ODR) is violated and the program has undefined behavior.
So remove everything you are showing from heap.cpp.
To define the constructors of heap in the heap.cpp file, you need to use this syntax:
#include "heap.h"
heap::heap() {
/*...*/
}
heap::heap(bool t) {
/*...*/
}
//...
and so on. The other member functions must be defined in a similar way, e.g.:
void heap::print() {
/*...*/
}
Furthermore, if you want to have a default member initializer as in
int capacity = 256;
add it in the declaration in the .h file instead.
I also want to add that having a pointer-to-std::vector as member is almost surely a wrong approach as well, but out-of-scope for the question.
When you declare a program element such as a class, function, or
variable, its name can only be "seen" and used in certain parts of
your program. The context in which a name is visible is called its
scope. For example, if you declare a variable x within a function, x
is only visible within that function body.
It seems you broke ODR rule so bad. Your class members including constructors has no body declared in the source file(heap.cpp).
Use '::' to make class members have a body:
//heap.cpp
"heap.h"
heap::heap()
{
}
heap:heap(vector<int> * input, bool t)
{
}
int heap::parent(int i)
{
return i;
}
// this is how you create a body for function that are class members
// the same should be done for all other functions

Function was not declared in this scope, even though header file is present

I'm trying to run some test code to learn c++, but I am getting an error telling me the reverseDigits function was not declared in the main.cpp scope:
error: 'reverseDigits' was not declared in this scope.
But the #include "Solutions.h" header was included in main.cpp, so I thought that it would be in scope.
I have checkout other questions, but the answers all relate to problems with circular header file inclusion, which I don't think is the problem here.
Do you know why I am seeing that error?
Solution.h
#ifndef SOLUTION_H
#define SOLUTION_H
class Solution {
public:
Solution();
~Solution();
int reverseDigits(int x);
};
#endif // SOLUTION_H
Solution.cpp
#include "Solution.h"
#include <string>
Solution::Solution()
{
}
Solution::~Solution()
{
}
int Solution::reverseDigits(int x) {
std::string num_string = std::to_string(x);
std::string reversed_num_string {};
for (int i = num_string.length() - 1; i > 0; i--) {
reversed_num_string.push_back(num_string[i]);
}
return stoi(reversed_num_string);
}
main.cpp
#include <iostream>
#include "Solution.h"
int main()
{
int x {123};
int result = reverseDigits(x);
std::cout << result << std::endl;
return 0;
}
You declared reverseDigits as a member function of the Solution class, then defined it without qualifying it as a member of Solution (Edit: You've since changed it to match declaration and definition, but at point of use, you're trying to use an unqualified function, not a member of a Solution object). The declaration in the .h file is visible, but the definition in the .cpp is unrelated, and not visible to main.cpp.
Declare the function outside the class (since it's clearly unrelated to the class), and it should work, changing to:
class Solution {
public:
Solution();
~Solution();
};
int reverseDigits(int x); // NOT inside the class definition
I'll note: I have no idea why you have a Solution class at all. Defining reverseDigits doesn't require it, so I'm not seeing the point. If this is part of some automated evaluation framework, you'll have to give more details
Along with ShadowRanger's valid suggestion, I'll highlight upon how you could have used the data as part of your Solution class and applied the function on it.
Refactoring your class to
class Solution {
public:
Solution(int data);
~Solution();
int reverseDigits();
private:
int m_data;
};
Solution::Solution(int data)
{
m_data = data;
}
Solution::~Solution()
{
}
Even though you could have used std::reverse, fixing the error on the i>=0 is needed to have your own reverse function
int Solution::reverseDigits() {
std::string num_string = std::to_string(m_data);
std::string reversed_num_string {};
for (int i = num_string.length() - 1; i >= 0; i--) {
reversed_num_string.push_back(num_string[i]);
}
return stoi(reversed_num_string);
}
Now call it from your main() as
int main() {
int x = 123;
Solution sol(x);
std::cout << sol.reverseDigits() << std::endl;
return 0;
}

Can't call a static method in Qt

I have a simple class containing a static attribute. There are two static methods in this class: one to get the static attribute and the other to initialize it. Yet when call the static method the compiler reports an error.
The class:
class Sudoku {
Cell Grid[9][9];
int CurrentLine;
int CurrentColumn;
void deleteValInColumn(int val, int col);
void deleteValInRow(int val, int row);
void deleteValInBox(int val, int x, int y);
static int unsetted; //!
public:
static void IniUnsetted() { //!
unsetted = 0;
}
static int GetUns() { //!
return unsetted;
}
Sudoku(ini InitGrid[9][9]);
void Calculate_Prob_Values();
Cell getCell(int x, int y);
QVector<int> getPossibleValues(int x, int y);
bool SolveIt();
};
This is the error I get:
In member function 'bool Sudoku::SolveIt()':
no return statement in function returning non-void [-Wreturn-type]
In function `ZN6Sudoku6GetUnsEv':
undefined reference to `Sudoku::unsetted` error: ld returned 1 exit status
You will need to define the static variable, even if it is not initialized explicitly. That is what is missing in your code. You should have provided a simple example to reproduce the issue, but for your convenience I am providing one which works.
main.cpp
class Foo {
public:
static int si;
static void bar();
};
int Foo::si = 0; // By default, it will be initialized to zero though.
void Foo::bar() {
Foo::si = 10;
};
int main()
{
Foo::bar();
return 0;
}
Note: I would suggest to get someone to review your code because "unsetted" is incorrect English. If we are at it, you would probably need to fix your indentation as well.
In your code there is no definition of unsetted, there is only declaration.
The solution is to put somewhere in your cpp file a line like this:
int Sudoku::unsetted
The reason for that is that each instantiation of Sudoku class will use the same unsetted member so it cannot be defined for each of them, so it's up to programmer to define it in one place only.
In your cpp file, define the static variable (ideally with an initialization):
int Sudoku::unsetted = 0;
If you are declaring any static variable in class, then you should define that variable outside the class also.
Example:
class A
{
public:
static int x; // declaration
};
int A::x; // definition

C++ static functions and variables

I have written a class as shown below:
#include<iostream>
using namespace std;
class A
{
static int cnt;
static void inc()
{
cnt++;
}
int a;
public:
A(){ inc(); }
};
int main()
{
A d;
return 0;
}
I want to call the function inc through the constructor, but when i compile i am getting an error as:
/tmp/ccWR1moH.o: In function `A::inc()':
s.cpp:(.text._ZN1A3incEv[A::inc()]+0x6): undefined reference to `A::cnt'
s.cpp:(.text._ZN1A3incEv[A::inc()]+0xf): undefined reference to `A::cnt'
I am unable to understand what the error is... plz help...
Static field is not defined - Take a look at Why are classes with static data members getting linker errors?.
#include<iostream>
using namespace std;
class A
{
static int cnt;
static void inc(){
cnt++;
}
int a;
public:
A(){ inc(); }
};
int A::cnt; //<---- HERE
int main()
{
A d;
return 0;
}
Inside the class static int cnt; is only declared, and need to be defined. In C++ you usually declare in your .h .hpp files and then define your static class members in your .c and .cpp files.
In your case, you need to add
int A::cnt=0; // = 0 Would be better, otherwise you're accessing an uninitialized variable.

Constructor errors

I have this class header
//header for class.
#ifndef Container_H
#define Container_H
#include <iostream>
using namespace std;
const int DEFAULT=32;
class Container{
public:
Container(int maxCapacity = DEFAULT);
~Container();
void insert(int item, int index);
void erase(int index);
int size()const;
private:
int sizeC;
int capacityC;
int * elements;
};
void info();
#endif
and this source file
#include "container.h"
Container::Container(int maxCapacity = DEFAULT){
int y;
}
void Container::insert(int item, int index){
int x;
}
and when I compile this, I get the following error message
test.cpp:4: error: default argument given for parameter 1 of `Container::Container(int)'
container.h:12: error: after previous specification in `Container::Container(int)
what have I done wrong here?
Functions with no arguments still need the parentheses:
Container::Container() {
int y;
}
Based on your header, it looks like you just forgot the maxCapacity argument, and it should actually be:
Container::Container(int maxCapacity) {
int y;
}
(If you're asking about the warning too, it's pretty self-evident -- you declared an int x but didn't do anything with it)
EDIT: Well now you've edited it to completely change the error. Now it's an error because you're specifying the default argument in both places; you're only supposed to specify it in the declaration. Leave it out in the actual implementation, like my second example above
Your Container constructor (in the source file) should be like this:
Container::Container(int maxCapacity){
// code
}
Container::Container{
int y;
}
I'm not sure what this is intended to be. If you're trying to define your ctor, it should look something like:
Container::Container(int maxCapacity) // ....
Note that you want to include the default value in the declaration, but not in the definition.
Container::Container{
int y;
} is syntactically incorrect.
EDIT:
Try this:
Container::Container(int maxCapacity) // default argument not to be mentioned in the definition
{
int y;
}