How to initialize a constant in a class? [duplicate] - c++

This question already has answers here:
How to initialize const member variable in a class?
(11 answers)
Closed 7 years ago.
So I've looked around and nothing I found has helped me so far.
I have the following header file for my class.
#ifndef CONGERA2_H
#define CONGERA2_H
typedef float Element300;
class Stack300
{
public:
Stack300 ();
Stack300 (const int);
Stack300 (Stack300 &old);
~Stack300();
void push300(const Element300);
Element300 pop300();
void viewTB300();
void viewBT300();
private:
const int MAX_STACK;
Element300 * stackArray;
int top;
};
#endif
And I'm trying to initialize MAX_STACK. If I set it equal to something I get a warning, which would normally be fine but I must transfer this code to Linux afterwards and I can't do that because it says that MAX_STACK is undefined in my three constructors. I've also tried defining it in my class functions file in the first constructor but then I get an error saying that MAX_STACK is not defined in the constructor.
Here is the constructors for my class functions if they are needed.
#include <iostream>
#include "congera2.h"
using namespace std;
Stack300::Stack300 (): MAX_STACK(10)
{
stackArray = new float[3];
for (int i = 0; i < 3; i++)
{
stackArray[i] = '\0';
}
top = -1;
return;
}
Stack300::Stack300 (const int size) : MAX_STACK (10)
{
stackArray = new float[MAX_STACK];
for (int i = 0; i < MAX_STACK; i++)
{
stackArray[i] = '\0';
}
top = -1;
return;
}
Stack300::Stack300 (Stack300 &old) : MAX_STACK (10)
{
top = old.top;
int i = 0;
while (top != old.top)
{
stackArray[i] = old.stackArray[i];
i = i + 1;
top = i;
}
}

Error:
class A
{
public:
const int x=8; // error (c++98/03)
};
Fix 1
class A
{
public:
const int x;
A() : x(8) // ok
{ }
};
Fix 2
class A
{
public:
const static int x;
};
const int A::x=8; // ok

Related

how do i initialize a public variable in a public class method

I have a public class in which I create an array, this array takes its size from the constructor and needs to be used in other functions (including int main). Therefore the variable must be public. my code looks something along these lines:
class myclass {
public:
int parameter1;
int parameter2;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
}
void makeArray() {
int array[parameter1][parameter2]; //I want this array to be public as the next method needs access to it
}
void otherFunction() {
array[1][2] = 5; //just an example of what i need to do
}
}
Look up how to use pointers and dynamic memory..
To do what you want would be something like:
class myclass {
public:
int parameter1;
int parameter2;
int **a;
myclass(int p, int p2) {
parameter1 = p;
parameter2 = p2;
a = nullptr;
}
~myclass() {
// TODO: delete "a"
}
void makeArray() {
// TODO: delete "a" if it has already been allocated
a = new *int[parameter1];
for (int i = 0; i < parameter1; ++i) {
a[i] = new int[parameter2];
}
}
void otherFunction() {
// TODO: check that "a" has already been allocated
a[1][2] = 5; //just an example of what i need to do
}
}
You could also allocate the array in the constructor since you have the necessary information being passed in already.
This is more optimized way to do the same thing:
class myclass {
public:
int parameter1;
int parameter2;
int *array;
myclass(int p1, int p2) {
parameter1 = p1;
parameter2 = p2;
}
void makeArray() {
array = new int[parameter1*parameter2];
}
void otherFunction() {
// ary[i][j] is then rewritten as ary[i*sizeY+j]
array[1*parameter2+2] = 5;
}
};
int main()
{
int sizeX = 5;
int sizeY = 5;
myclass m1(sizeX,sizeY);
m1.makeArray();
m1.otherFunction();
cout << m1.array[1*sizeY+2] << endl;
return 0;
}

Keep getting "cygwin_exception::open_stackdumpfile" while dynamically allocating 2-D array in a class

I have been attempting to write this program where I am required to utilize dynamically allocated arrays to print out a 2d matrix. I am only to write the cpp files and not allowed to modify anything in the header files.
I keep getting an exception
0 [main] review2_cis17c_objectarray 4018 cygwin_exception::open_stackdumpfile: Dumping stack trace to review2_cis17c_objectarray.exe.stackdump
I am relatively new to learning c++; after contemplating, I think something is wrong in my PlusTab.cpp, where I am trying to assign an allocated address to a constructor-defined array in a class. Can someone please help and let me know here I did wrong in the project? Thank you very much!
AbsRow.h:
class AbsRow {
protected:
int size;
int *rowData;
public:
virtual int getSize()const = 0;
virtual int getData(int)const = 0;
};
AbsTabl.h:
class AbsTabl {
protected:
int szRow;
int szCol;
RowAray **columns;
public:
virtual int getSzRow()const = 0;
virtual int getSzCol()const = 0;
virtual int getData(int,int)const = 0; };
PlusTab.h
class PlusTab:public Table {
public:
PlusTab(unsigned int r,unsigned int c):Table(r,c){};
PlusTab operator+(const PlusTab &);
};
RowAray.h
class RowAray:public AbsRow {
public:
RowAray(unsigned int);
virtual ~RowAray();
int getSize()const{return size;}
int getData(int i)const{
if(i>=0&&i<size)return rowData[i];
else return 0;}
void setData(int,int);
};
Table.h
#include "AbsTabl.h"
class Table:public AbsTabl {
public:
Table(unsigned int,unsigned int);
Table(const Table &);
virtual ~Table();
int getSzRow()const {return szRow;}
int getSzCol()const {return szCol;}
int getData(int,int)const;
void setData(int,int,int);
};
PlusTab.cpp:
#include "PlusTab.h"
PlusTab PlusTab::operator+(const PlusTab &t) {
PlusTab tab(this->getSzRow(), this->getSzCol());
for(int i = 0; i < tab.getSzRow(); i++) {
for (int j = 0; j <tab.getSzCol(); j++) {
(tab.columns[i])->setData(j, this->getData(i,j) + t.getData(i,j));
}
}
return tab;
}
RowAray.cpp:
#include "RowAray.h"
RowAray::RowAray(unsigned int c) {
size = c;
rowData = new int[c];
}
RowAray::~RowAray() {
delete []rowData;
}
void RowAray::setData(int i, int value) {
rowData[i] = value;
}
Table.cpp:
#include "Table.h"
#include <cstdlib>
Table::Table(unsigned int r, unsigned int c) {
szRow = r;
szCol = c;
columns = new RowAray*[r];
for (int i = 0; i < r; i++) {
columns[i] = new RowAray(c);
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
columns[i]->setData(j, (rand()%90 + 10));
}
}
}
Table::~Table() {
for (int i = 0; i < szRow; i++) {
delete []columns[i];
}
delete []columns;
}
Table::Table(const Table &t) {
szRow = t.szRow;
szCol = t.szCol;
columns = t.columns;
};
int Table::getData(int r ,int c) const {
return columns[r]->getData(c);
};
void Table::setData(int r, int c, int value) {
columns[r]->setData(c,value);
}
and finally my main.cpp, which I am not allowed to modify either.
#include <ctime>
#include <iostream>
#include <iomanip>
using namespace std;
//User Libraries
#include "PlusTab.h"
//Global Constants
//Function Prototype
void prntTab(const Table &);
//Execution Begins Here!
int main(int argc, char** argv) {
//Initialize the random seed
srand(static_cast<unsigned int>(time(0)));
//Declare Variables
int rows=3,cols=4;
//Test out the Tables
PlusTab tab1(rows,cols);
PlusTab tab2(tab1);
PlusTab tab3=tab1+tab2;
// Print the tables
cout<<"Abstracted and Polymorphic Print Table 1 size is [row,col] = ["
<<rows<<","<<cols<<"]";
prntTab(tab1);
cout<<"Copy Constructed Table 2 size is [row,col] = ["
<<rows<<","<<cols<<"]";
prntTab(tab2);
cout<<"Operator Overloaded Table 3 size is [row,col] = ["
<<rows<<","<<cols<<"]";
prntTab(tab3);
//Exit Stage Right
return 0;
}
void prntTab(const Table &a){
cout<<endl;
for(int row=0;row<a.getSzRow();row++){
for(int col=0;col<a.getSzCol();col++){
cout<<setw(4)<<a.getData(row,col);
}
cout<<endl;
}
cout<<endl;
}
I apologize for this massive amount of code. This is my first time posting, will learn to use the website! I appreciate your help:)

Exception Error C++ //Visual Studio [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
So im creating an engine from scrath(learnign purposes).
And when i test my TArray i get an Execption thrown in my Memory.h file. This happens only when im trying to test the TArray
Here is my code for TArray.h
#pragma once
#include "Memory/DynamicLinearStackAllocator.h"
template <typename T, typename Allocator = DynamicLinearStackAllocator>
class TArray
{
private:
Allocator m_Allocator;
uint32 m_ElementCount;
public:
FORCEINLINE TArray()
{
}
FORCEINLINE ~TArray()
{
m_Allocator.Destroy();
}
FORCEINLINE TArray(const uint32 InElementCount)
{
m_Allocator.Resize<T>(InElementCount, m_ElementCount);
m_ElementCount = InElementCount;
}
FORCEINLINE void Add(const T &InValue)
{
}
FORCEINLINE T* GetData() const { return m_Allocator.GetAllocator<T>(); }
FORCEINLINE uint32 Num() const
{
return m_ElementCount;
}
FORCEINLINE T& operator[](uint32 InElementIndex) const
{
check(m_ElementCount > InElementIndex);
return GetData()[InElementIndex];
}
};
namespace Tests
{
FORCEINLINE void TestArrays()
{
{
TArray<float> data(10);
check(data.Num() == 10);
for(uint32 i = 0; i < data.Num(); i++)
{
data[i] = 2.0f;
}
check(data[0] == 2.0f);
}
{
TArray<uint32> data(5);
data[0] = 10;
data[1] = 5;
check(data.Num() == 5);
check(data[0] == 10);
check(data[1] == 5);
}
{
TArray<float> data(1);
data[2] = 2.0f;
}
}
}
When i try to compile(Im using Visual Studio 2017) it gives me an execption error at this position in Memory.h
static void* Copy(void *InDestination, const void *InSource, size_t InSize)
{
check_slow(InDestination);
check_slow(InSource);
check_slow(InSize > 0);
return memcpy(InDestination, InSource, InSize);
}
The test is getting called in the main function with this code:
int main()
{
Tests::TestAssertion();
Tests::TestMemory();
Tests::TestAllocator();
Tests::TestArrays();
return 0;
}
my goal currently is to look if the logger shows me the error here:
{
TArray<float> data(1);
data[2] = 2.0f;
}
here is a screenshot of the full error https://gyazo.com/6c1d6779623ffea97504f5b23f9fd7da
edit: here is the code for the allocator
#pragma once
#include <malloc.h>
#include "Core.h"
#define MEMORY_ALIGMENT 16
struct Memory
{
// TODO:Rework types.
static void* Allocate(const int32 InCount, const size_t InSize)
{
check_slow(InCount > 0);
check_slow(InSize > 0);
const size_t size = InSize * InCount;
return _aligned_malloc(size, MEMORY_ALIGMENT);
}
static void Free(void *InBlock)
{
check_slow(InBlock);
_aligned_free(InBlock);
}
static void* Copy(void *InDestination, const void *InSource, size_t InSize)
{
check_slow(InDestination);
check_slow(InSource);
check_slow(InSize > 0);
return memcpy(InDestination, InSource, InSize);
}
};
void* operator new (size_t InSize)
{
return Memory::Allocate(1, InSize);
}
void operator delete (void* InBlock)
{
Memory::Free(InBlock);
}
namespace Tests
{
struct MemoryTestStruct
{
uint32 p0;
uint32 p1;
uint32 p2;
uint32 p3;
};
FORCEINLINE void TestMemory()
{
MemoryTestStruct *t = new MemoryTestStruct();
check(t);
delete t;
}
}
edit2: Here is the code for the StackAlloctor
#pragma once
#include "../Core.h"
class DynamicLinearStackAllocator
{
private:
void *m_Data;
public:
template <typename T>
FORCEINLINE void Resize(const uint32 InElementCount, const uint32 InPreviousElementCount)
{
void *temp = Memory::Allocate(InElementCount, sizeof(T));
if (InPreviousElementCount > 0)
{
const SIZE_T size = sizeof(T) * InPreviousElementCount;
Memory::Copy(temp, m_Data, size);
Memory::Free(m_Data);
}
m_Data = temp;
}
template <typename T>
FORCEINLINE T* GetAllocator() const
{
return (T*)m_Data;
}
FORCEINLINE void Destroy()
{
Memory::Free(m_Data);
}
};
namespace Tests
{
FORCEINLINE void TestAllocator()
{
DynamicLinearStackAllocator alloc;
alloc.Resize<float>(2, 0);
alloc.Destroy();
}
}
You're not showing the code for your Allocator, but the problem is probably this line in your TArray constructor:
m_Allocator.Resize<T>(InElementCount, m_ElementCount);
At this point, m_ElementCount has not been initialized and will have some random value in it. Resize is then probably trying to free up memory that hasn't been allocated (because of the uninitialized value in m_ElementCount). You should pass in a 0 for the second parameter of the Resize call in your constructor
m_Allocator.Resize<T>(InElementCount, 0);
since there is no existing allocated memory to free.
Also, your default constructor for TArray should initialize m_Allocator.m_data to nullptr (or add a default constructor to DynamicLinearStackAllocator to do that) and set m_ElementCount to 0.

Class Not Declared in Scope

Getting a "throttle not declared in this scope" error when I attempt to compile the main.cpp. I am very new to c++, so bear with me. I have the #include "throttle.h" in the headers for both cpp files, so I am not sure why when i try to create a throttle object is is not declared...
main.cpp file:
#include <stdio.h>
#include "throttle.h"
using namespace std;
int main(int argc, char **argv)
{
throttle throt1(5, 0);
throttle throt2(4, 0);
return 0;
}
throttle.h file:
#ifndef MAIN_SAVITCH_THROTTLE
#define MAIN_SAVITCH_THROTTLE
namespace main_savitch_2A
{
class throttle
{
public:
// CONSTRUCTORS
//throttle( );
//throttle(int size);
throttle(int size = 1, int start = 0); //by adding this default
//constructor the other two
//are not needed
// MODIFICATION MEMBER FUNCTIONS
void shut_off( ) { position = 0; }
void shift(int amount);
// CONSTANT MEMBER FUNCTIONS
double flow( ) const
{
return position / double(top_position);
}
bool is_on( ) const
{
return (position > 0);
}
int get_top_position()const;
int get_position()const;
friend bool operator <(const throttle& throt1, const throttle& throt2);
//postcondtion: returns true if flow of throt1 < flow of throt2.
//return false if flow of throt1 > flow of throt2
private:
int top_position;
int position;
};
}
#endif
throttle.cpp file :
#include <cassert> // Provides assert
#include "throttle.h" // Provides the throttle class definition
using namespace std; // Allows all Standard Library items to be used
namespace main_savitch_2A
{
//throttle::throttle( )
//{ // A simple on-off throttle
//top_position = 1;
//position = 0;
//}
//throttle::throttle(int size)
// Library facilities used: cassert
//{
//assert(size > 0);
//top_position = size;
//position = 0;
//}
throttle::throttle(int size, int start)
{
assert(size > 0);
assert(start = 0);
top_position = size;
position = start;
}
void throttle::shift(int amount)
{
position += amount;
if (position < 0)
position = 0;
else if (position > top_position)
position = top_position;
}
bool operator <(const throttle& throt1, const throttle& throt2)
{
return(throt1.flow() < throt2.flow());
}
int throttle::get_top_position()const
{
return top_position;
}
int throttle::get_position()const
{
return position;
}
}
In your main, it should be main_savitch_2A::throttle throt1(5, 0);.
The same for throt2.
See namespaces for further details.

Declaring the templates in c++

// stdafx.h
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>
using namespace std;
#include "Animal.h"
// TODO: reference additional headers your program requires here
class Animal
{
private:
int itsWeight;
public:
Animal(int);
Animal();
~Animal() {}
int getWeight() const { return itsWeight; }
void Display() const;
};
template <class T>
class Array
{
private:
T *pType;
int itsSize;
const int defaultSize = 10;
public:
//constructors
Array(int itsSize = defaultSize);
Array(const Array &rhs);
~Array() { delete[] pType; }
//operators
Array& operator=(const Array&);
T& operator[](int offSet){ return pType[offSet]; }
const T& operator[](int offSet) const { return pType[offSet]; }
//methods of Access
int getSize() const { return itsSize; }
};
//constructor
template <class T>
Array<T>::Array(int size) :
itsSize(size)
{
pType = new T[size];
for (int i = 0; i < size; i++)
{
pType[i] = 0;
}
}
//copy-constructor
template <class T>
Array<T>::Array(const Array &rhs)
{
itsSize = rhs.getSize();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
{
pType[i] = rhs[i];
}
}
//operator prisvoeniya
template <class T>
Array<T>& Array<T>::operator=(const Array &rhs)
{
if (this == &rhs)
return *this;
delete[] pType;
itsSize = rhs.getSize();
pType = new T[itsSize];
for (int i = 0; i < itsSize; i++)
{
pType[i] = rhs[i];
}
return *this;
}
//this is the file "Animal.cpp"
#include "stdafx.h"
#include "Animal.h"
Animal::Animal()
{
itsWeight = 0;
}
Animal::Animal(int weight)
{
itsWeight = weight;
}
void Animal::Display() const
{
cout << itsWeight;
}
// the main function
#include "stdafx.h"
int_tmain(int argc, _TCHAR* argv[])
{
Array<int> theArray; //Integer array
Array<Animal> theZoo; //Animal array
Animal *pAnimal;
//filling the array
for (int i = 0; i < theArray.getSize(); i++)
{
theArray[i] = i * 2;
pAnimal = new Animal[i * 3];
theZoo[i] = *pAnimal;
delete pAnimal;
}
for (int j = 0; j < theArray.getSize(); j++)
{
cout << "theArray[" << j << "]:\t";
cout << theArray[j]<<"\t\t";
cout << "theZoo[" << j << "]:\t";
theZoo[j].Display();
cout << endl;
}
return 0;
}
The problem is that: The compiler gives me the errors
Error 1 error C2648: 'Array<int>::defaultSize' : use of member as default parameter requires static member
d:\documents\work\c++ files\tigrans\homework10\templates\templates\templates\animal.h 28 1 Templates
Error 2 error C2648: 'Array<Animal>::defaultSize' : use of member as default parameter requires static member
d:\documents\work\c++ files\tigrans\homework10\templates\templates\templates\animal.h 28 1 Templates
Anybody can help me to understand that. I change the
const int defaultSize=10;
to
static const int defaultSize=10
then there is not errors but in that time show Debug Assertion Failed!
This part of your code is dodgy
{
pAnimal = new Animal[i * 3];
theZoo[i] = *pAnimal;
delete pAnimal;
}
The first line allocates an array of i*3 Animals, using their default constructor (which makes an Animal with itsWeight=0). In the second line you assign the first these newly allocated Animals to theZoo[i]. Finally, the third line tries to de-allocate the Animals.
The last line contains an error, since you call delete on a pointer obtained with new [].
The whole concept of creating objects on the heap only to immediately destroy them is quite dubious -- perhaps you come from another programming language, where this is the only way to create things? First, you could simply use an automatic variable
{
Animal a; // or a(i*3);
theZoo[i] = a;
}
or yet briefer
{
theZoo[i] = Animal(i*3);
}
(Note the if you would use a std container, you could say theZoo.emplace_back(i*3);, avoiding the copy of Animal.)