using an abstract class from another header file in c++ - c++

I have 3 files
dimentions.h:
namespace mtm {
class Dimensions {
int row, col;
//some code
};
}
IntMatrix.h:
#include "dimentions.h"
namespace mtm
{
class intMatrix
{
private:
int** data;
int col;
int row;
public:
intMatrix(Dimensions dims, int num=0);
//some code
};
//the line bellow is where I get the error
intMatrix(Dimensions dims, int num=0): col(dims.getCol()),row(dims.getRow()) ,data(new int*[dims.getRow()])
{
for(int i=0;i<dims.getCol())
{
data[i](new int[dims.getCol]);
}
for(int i=0;i<dims.getRow();i++)
{
for(int j=0;j<dims.getCol();j++)
{
data[i][j]=num;
}
}
}
}
the compiler says: expected ‘)’ before ‘dims’
and when I put the mouse at dims, vs code says: " error-type mtm::dims"
but dims is not a type it is a vriable.
IntMatrix.cpp:
#include "IntMatrix.h"
using namespace mtm;
//some code
in IntMatrix.cpp the problem is that it doesn't recognize what Dimentions is , however it does recognize what intMatrix is.

Welcome to StackOverflow!
Compiler messages are sometimes misleading, and in your case you have an error because you are repeating the default value in your implementation. This is probably the error the compiler is complaining about.
EDIT
As pointer out by drescherjm, you also forgot the add the class name to the constructor
The correct definition should be :
intMatrix::intMatrix(Dimensions dims, int num): ...
Please let me know if you still have the error after that.

In your C++ source code the constructor must be defined as
intMatrix::intMatrix(Dimensions dims, int num) ....
So you have two mistakes: you have to add intMatrix and delete =0
But do not ever write a matrix class like this. This is terrible C++ code. You should never need to call new directly. And your data, in this case, is laid down very cache unfriendly

Related

'CustomVector<int,15>::size': cannot access private member declared in class 'CustomVector<int,15>'

I am so confused right now...
Here is the code that I will be talking about:
main.cpp:
#include "CustomVector.h"
#include <iostream>
int main() {
CustomVector<int, 15> hello{};
std::cout << hello.size() << '\n';
return 0;
}
CustomVector.h:
#pragma once
template<typename T, int S>
class CustomVector {
private:
T arr[S];
int size;
public:
CustomVector() : arr{}, size{ S } {}
// Methods
int size() const {
return size;
}
};
As you can see I am trying to use the size() method that I have in my class definition, which there shouldn't be a problem with, right..? But when I try to use it in main.cpp and try to print it out to the console, it is giving me the compiler error which my question title has. Why could this be, this has never happened to me before. I would think there is some sort of "redefinition" somehow, but how could that be, there couldn't be a redefinition if it is in my own user-defined class?

Read Matrix from file, give it to main

I have a fairly simple program. It reads a matrix from a file that looks like this
4 4
a b c d
a b c d
a b c d
a b c d
and outputs it in the console. The program is working as intended:
#include <iostream>
#include <fstream>
using namespace std;
int main() {
int n, m;
ifstream myfile;
myfile.open ("matrix.txt");
myfile >> n >> m;
char mat[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
myfile >> mat[i][j];
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
cout << mat[i][j];
}
cout << endl;
}
return 0;
}
Now this program is going to grow a lot, so I want to start using headerfiles and declare the functions external so that my main looks more like
int main() {
readMat();
printMat();
}
My Problem is, I don't really know how to do this right. Where should I declare the matrix so that both functions can "see" it? I can't declare it globally as char mat[n][m] because I only know n and m inside readMat().
Or is my whole design flawed and there is much better way to do this?
I would be grateful for every little tip.
I have not worked with multiple files in c++ yet.
You cannot use an array like that, when not just multiple translation units, but multiple functions are involved.
Any function needs to know the exact data types it receives as parameters, and this must be declared at compile time.
Here, you don't know the type of the array until runtime. array[10] and array[15] are different types. Don't be fooled by the fact their name might be the same. It's not the name that matters, but the type, like int [10] or int [11].
You have two basic options:
Use templates.
Convert your array to a std::vector<std::vector<int>>. Then you can declare the array (now a vector) globally, and/or pass it as a parameter to your multiple functions.
Matrix.h
#ifndef MATRIX_H
#define MATRIX_H
namespace mynamespace {
template <class T>
class Matrix {
private:
int m_rows;
int m_columns;
T** m_data;
public:
Matrix(); // Default Constructor - Null or Empty Matrix
Matrix( const int rows, const int columns ); // Empty Matrix With Defined Size
Matrix( const int rows, const int columns, const T** data ); // Defined Matrix
T** getData() const;
}; // Matrix
#include "Matrix.inl"
} // mynamespace
#endif // MATRIX_H
Matrix.inl
// Matrix Constructor and Function Implementations Here
Matrix.cpp
#include "Matrix.h"
Main.cpp
#include <string>
#include <iostream>
#include <fstream>
#include "Matrix.h"
using namespace mynamespace;
void readMatrix( std::fstream& fin, const std::string& strFilename, Matrix& matrixIn );
void printMatrix( const Matrix& matrix );
int main() {
std::fstream fileIn; // Prefer to not use "using namespace std;"
std::string strFilename( "Matrix.txt" );
Matrix<type> mat(); // Default Empty Matrix To Be Filled In
readMatrix( fileIn, strFilename, mat );
printMatrix( mat );
return 0;
} // main
void readMatrix( std::fstream& fin, const std::string& strFilename, Matrix& mat ) {
// Do Work Here To Populate Matrix Object
} // readMatrix
void printMatrix( Matrix& mat ) {
// Do Work Here To Print Matrix Being Passed In
} // printMatrix
With this pseudo code, the design here allows any type of matrix to be constructed. The matrix is an object of a template type. The implementation of generating a matrix by reading in data from a file, and the implementation of displaying or printing that matrix are independent of the class itself. This allows for the matrix class to be as generic as possible without having to rely on any other libraries. The functions that do the work are stand alone functions that accept a matrix object. A modification may be needed in your text or binary file to work with this construct.
matrix.txt
type
4 4
a b c d
a b c d
a b c d
a b c d
The only problem with this, is it should already be obvious: you need to define what type of data this matrix will hold when instantiating it. Yet you do not know the type until after you read the file in. So this code does have a bug in it that would need to be address. However, the overall design method used here is to only show how to keep similar code objects contained with in their own class object while separating independent code blocks that does work on them. Now other class objects may have a file reading and print methods, but normally Vector (math & not containers) and Matrix classes usually don't.

How to include a declaration in the comma operator?

I have two simple testing lines:
cout<<(cout<<"ok"<<endl, 8)<<endl;
cout<<(int i(8), 8)<<endl;
The first line worked, but the second failed compilation with
error: expected primary-expression before 'int'
For some reason, I do need a declaration in the comma operator. To be more specific, I want to declare some variables, obtain their values, and assign them to my constant class members from the initialization list of my class constructor. Following shows my intentions. If not achievable using comma operator, any another suggestions?
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <cstdlib>
using namespace std;
void readFile(const string & fileName, int & a, int & b)
{
fstream fin(fileName.c_str());
if (!fin.good()) {cerr<<"file not found!"<<endl; exit(1);}
string line;
getline(fin, line);
stringstream ss(line);
try {ss>>a>>b;}
catch (...) {cerr<<"the first two entries in file "<<fileName<<" have to be numbers!"<<endl; exit(1);}
fin.close();
}
class A
{
private:
const int _a;
const int _b;
public:
A(const string & fileName)
:
_a((int a, int b, readFile(fileName,a,b), a)),
_b((int a, int b, readFile(fileName,a,b), b))
{
/*
int a, b;
readFile(fileName,a,b);
_a = a;_b = b;
*/
}
void show(){cout<<_a<<" "<<_b<<endl;}
};
int main()
{
A a("a.txt");
a.show();
}
Declarations are statements and not expressions. You cannot place statements inside of expressions, though you can place expressions inside of statements. Accordingly, you cannot declare a variable in the way that you're describing above. You'll need to separate it out into multiple different statements.
I would be surprised if if you actually needed to do this. If you do, there is probably something problematic about your design.
Hope this helps!
You should have a look at Boost Phoenix (which has phoenix::let to do roughly this). Bear in mind, Phoenix is an eDSL, really (embedded domain specific language).
You could do an ugly trick and abuse lambdas:
cout<< ([]->int{ int i(8); return 8; })() <<endl;
A lambda allows a declaration within an expression. So this is possible:
std::cout << ([]{ int i(8); m_i = i; }(), 8) << std::endl;
But it's really weird - I assume this will be in some #define macro that makes it appear closer to normal.
You cannot. This is unpossible in C++. The fact that you are trying to do this is also a code smell. Something's not right here.
I want to declare some variables, obtain their values, and assign them
to my constant class members from the initialization list of my class
constructor. Not sure how to achieve this.
You didn't say what you intended to do with these variables you declare after you've used the values, but I'm guessing that once you've finished with the values, you've finished with the variables. In other words, they are temporary.
Your edited example suggests that my assumption is correct. It also confirms the code smell. Based on your (intended) code, you are going to read the file twice.
I'd say the most straightforward way to do this is to use an intermediary, kind of like a factory class. This also has the benefit of being able to read the file only once, as opposed to twice as you are doing now.
void readFile (const std::string& fileName, int& a, int& b)
{
// some magic
a = 42;
b = 314;
}
class FileReader
{
public:
FileReader (const std::string fileName)
:
mFileName (fileName),
mA (42),
mB (314)
{
// something happens like reading the file
}
int GetA () const
{
return mA;
}
int GetB () const
{
return mB;
}
private:
int mA;
int mB;
std::string mFileName;
};
class A
{
private:
const int mA;
const int mB;
public:
A (const FileReader& reader)
:
mA (reader.GetA()),
mB (reader.GetB())
{
}
};
Using this FileReader is simple:
int main()
{
A myA (FileReader ("somefile.txt"));
}

size of ArrayList is not known help

I have this code
main.cpp
#include <iostream>
#include "functs.h"
using namespace std;
int main()
{
ArrayList *al = new ArrayList;
return 0;
}
functs.h
using namespace std;
#ifndef FUNCTS_H_INCLUDED
#define FUNCTS_H_INCLUDED
class ArrayList;
#endif // FUNCTS_H_INCLUDED
functs.cpp
#include <iostream>
#include "functs.h"
class ArrayList{
public:
void add(int num);
void add(int num, int index);
void remove(int index);
void removeNum(int num);
string toString();
ArrayList(int init);
private:
void resize();
int size, cap;
int *myList[10];
};
void ArrayList::add(int num){
if (size>=cap/2)
{
resize();
}
*myList[size] = num;
size++;
}
void ArrayList::resize(){
int temp[cap*2];
int i;
for (i = 0; i < size; i++)
{
temp[i] = *myList[i];
}
*myList = temp;
}
ArrayList::ArrayList(){
size = 0;
cap = 10;
}
void ArrayList::add(int num, int index){
int temp = *myList[index];
int i;
for (i = index; i < size; i++)
{
*myList[index] = num;
num = temp;
temp = *myList[i+1];
}
add(temp);
}
string ArrayList::toString(){
string returnString = "{";
int i;
for (i = 0; i < size; i++)
returnString.append(*myList[i] +",");
returnString.replace(returnString.length()-1,1,"}");
return returnString;
}
and I'm extremely new to C++ but whenever I try to compile the code it gives me a "size of ArrayList is not know". Please help me figure out the error. =(
Design/usage problems in your code notwithstanding, the most obvious problem is that you want to put the class definition in the functs.h file instead of the functs.cpp file:
functs.h:
// This is declaration is highly not recommended for use in header files.
// using namespace std;
#ifndef FUNCTS_H_INCLUDED
#define FUNCTS_H_INCLUDED
#include <string>
class ArrayList{
public:
void add(int num);
void add(int num, int index);
void remove(int index);
void removeNum(int num);
std::string toString();
ArrayList(int init);
private:
void resize();
int size, cap;
int *myList[10];
};
#endif // FUNCTS_H_INCLUDED
functs.cpp:
#include "functs.h"
void ArrayList::add(int num){
if (size>=cap/2)
{
resize();
}
*myList[size] = num;
size++;
}
void ArrayList::resize(){
int temp[cap*2];
int i;
for (i = 0; i < size; i++)
{
temp[i] = *myList[i];
}
*myList = temp;
}
ArrayList::ArrayList(){
size = 0;
cap = 10;
}
void ArrayList::add(int num, int index){
int temp = *myList[index];
int i;
for (i = index; i < size; i++)
{
*myList[index] = num;
num = temp;
temp = *myList[i+1];
}
add(temp);
}
std::string ArrayList::toString(){
std::string returnString = "{";
int i;
for (i = 0; i < size; i++)
returnString.append(*myList[i] +",");
returnString.replace(returnString.length()-1,1,"}");
return returnString;
}
templatetypedef provides a reason why this is necessary. Basically the compiler needs to know how much space an ArrayList needs, and a class ArrayList; provides no such information.
It's not a good idea to declare using namespace std; inside a header file, because then everyone that includes the functs.h file (including your clients!) will also have a using namespace std;, increasing the possibility of name collisions.
I highly recommend that you pick up a good introductory C++ book if you wish to learn C++ properly. You demonstrate in your question a rather big misunderstanding of how good C++ is written. That's not to say you're incompetent as a person, but there are some serious problems with the code you present. Just to name a few:
Standard C++ already provides a perfectly fine array class called std::vector. There's no need to reinvent the wheel for what you're doing. And even if you have to reinvent the wheel, an advanced understanding of C++ and plenty of C++ experience is a prerequisite to implementing an array container that's appropriate for production use.
The public interface of your class is incomplete. There's no way for clients to know how many elements are actually in the array.
int *myList[10]; declares a fixed array of 10 pointers to an int. This is not appropriate for an array class. Especially if you want the array to be resizable.
There's not sufficient memory management for this class to be useful in any sense. There are no destructors and apparently the constructors are not complete (nor do they match), so you have no real logical place to put things like new[] and delete[].
You have a ArrayList *al = new ArrayList; but you don't have a corresponding delete al; anywhere. This is a memory leak.
But the last point is moot because you should be using ArrayList a1; instead of ArrayList *al = new ArrayList;. The former will automatically "delete" itself at the end of the scope (in this case, the main() function) while the latter requires a delete statement. C++ is not like Java where unused new'ed objects are automatically collected.
I can't comment on the correctness of the algorithms you used, because (and I'm sorry to say this because it'll sound harsh) what you have simply won't work. Again, I recommend that you pick up a good introductory C++ book, which will cover these kinds of issues. (I must emphasize that none of these shortcomings are a statement of you as a person. I'm talking specifically about the code you have in your question.)
The reason that you're getting this error is that in main.cpp, the compiler hasn't seen the definition for the class ArrayList. It's only seen the declaration
class ArrayList;
When you try to create the ArrayList by writing
new ArrayList;
The compiler doesn't know how much memory is needed to hold an ArrayList because it hasn't seen the class definition. This contrasts with other languages like Java, where this information doesn't have to immediately be available.
To fix this, update your .h file by moving the definition of the class from the .cpp file. That way, when someone #includes the header file, they'll get the class definition in addition to the declaration, which will allow you to use new, declare local variables of type ArrayList, etc.
Hope this helps!
This much
class ArrayList{
public:
void add(int num);
void add(int num, int index);
void remove(int index);
void removeNum(int num);
string toString();
ArrayList(int init);
private:
void resize();
int size, cap;
int *myList[10];
};
Should be in the .h file.
Why? Because the declaration of a class (when you write class ArrayList;) is only enough when the size of the class is not needed (more specific cases are listed in the C++ standard). The definition of the class should appear in the same translation unit in which the class is used in a way in which it is required to be complete.
The way you've declared myList it has a fixed size; *myList = temp; isn't doing what you want it to.
Declare myList simply as int *myList;
In the constructor, use myList = new int[10];
Everywhere you have *myList[...] change it to myList[...]
In resize, int temp[cap*2] needs to be int *temp = new int[cap * 2] and *myList = temp needs to be myList = temp
You'll still have a memory leak, but that should get you started.

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;
}