This question already has answers here:
Initialize base class with no default constructor in constructor of derived class
(3 answers)
Closed 3 years ago.
I'm learning oop in c++ and have the following error:
In constructor 'pflFr1::pflFr1()'
Error: No matching function for call to worldBuilder::worldBuilder()
The class worldbuilder is generating protected 2d arrays. The class pflfr1 is inherting from worldbuilder. But somehow, the constructor of worldbuilder has a problem.
My code:
main.cpp:
#include <iostream>
#include "pflfr1.h"
#include "worldbuilder.h"
#include <vector>
using namespace std;
int main()
{
srand(time(0));
int sl = 10;
worldBuilder w_obj(sl);
w_obj.buildPhyWelt();
w_obj.buildVegWelt();
pflFr1 objekt();
return 0;
}
worldbuilder.h:
#ifndef WORLDBUILDER_H
#define WORLDBUILDER_H
#include <vector>
using namespace std;
class worldBuilder
{
public:
worldBuilder(int sl_);
vector<vector<int> > buildPhyWelt();
vector<vector<int> > buildVegWelt();
protected:
vector<vector<int> > phyWelt;
vector<vector<int> > vegWelt;
int sl;
private:
};
#endif // WORLDBUILDER_H
worldbuilder.cpp:
#include <iostream>
#include "worldbuilder.h"
#include <vector>
using namespace std;
worldBuilder::worldBuilder(int sl_)
: sl(sl_)
{
}
vector<vector<int> > worldBuilder::buildPhyWelt()
{
phyWelt.resize(sl, vector<int>(sl));
// initialisiere physische Welt
// 1 = land, -1 ist meer
for(int i=0; i<sl; i++)
{
for(int j=0; j<sl; j++)
{
phyWelt[i][j] = 1;
}
}
}
vector<vector<int> > worldBuilder::buildVegWelt()
{
vegWelt.resize(sl, vector<int>(sl));
// initialisiere Nahrung
for(int i=0; i<sl; i++)
{
for(int j=0; j<sl; j++)
{
if(rand()%100<=2)
{
vegWelt[i][j] = 1;
}
else
{
vegWelt[i][j] = 0;
}
}
}
}
pflfr1.h:
#ifndef PFLFR1_H
#define PFLFR1_H
#include <vector>
#include "worldbuilder.h"
using namespace std;
class pflFr1: protected worldBuilder
{
public:
pflFr1();
protected:
private:
int y;
int x;
int hp;
};
#endif // PFLFR1_H
pflfr1.cpp:
#include <iostream>
#include <pflfr1.h>
#include <cstdlib>
#include <ctime>
using namespace std;
pflFr1::pflFr1()
: hp(10)
{
int initPosY = rand()%sl;
int initPosX = rand()%sl;
y = initPosY;
x = initPosX;
}
Your default constructor pflFr1::pflFr1() 's implementation is rewritten as
pflFr1::pflFr1()
: worldBuilder(), hp(10){
...
}
Because the pflFr1 class derives from worldBuilder, its constructor must be called as part of pflFr1 object creation. The default behaviour is to call the default constructor of the base - worldBuilder().
But this constructor does not exist. You only declared worldBuilder::worldBuilder(int sl_);. By doing so you disabled the automatic generation of default constructors for classes, which is done only if no user-defined constructor was declared.
Either you can write worldBuilder()=default; inside the class, which will leave s1 uninitialized. Or you can use delegating constructors - worldBuilder():worldBuilder(0){}.
Related
I'm trying to build a class named "Tombola" which should contain as private variable an empty vector. This should be filled at runtime through the class member Tombola.estrai(), which generates a random number and insert it inside the vector named "order" by the method order.push_back(number). This is the class definition in the tombola.h header:
#ifndef TOMBOLA_H
#define TOMBOLA_H
#include <cstdlib>
#include <vector>
using namespace std;
class Tombola {
private:
bool on_off[90];
int tabellone[9][10];
int x_max = 9;
int y_max = 10;
vector<int> order;
public:
Tombola();
~Tombola();
void nuovo();
int estrai();
bool completato();
void stampa();
void stampa_tab();
};
#endif
And this is the implementation of constructor/destructor and Tombola::estrai() inside tombola.cc:
#include "tombola.h"
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <vector>
#include <iostream>
using namespace std;
Tombola::Tombola () {
vector<int> ord;
order = ord;
int z=1;
for(int i=0;i<90;i++) {
on_off[i] = false;
}
for(int j=0;j<=x_max;j++) {
for (int k=0;k<=y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
}
Tombola::~Tombola() {
cout << "Tombola is destroyed" << endl;
}
int Tombola::estrai() {
srand(time(NULL));
int estrazione = int(ceil(rand()/double(RAND_MAX)*90));
on_off[estrazione]==true;
order.push_back(estrazione);
return order.back();
}
and this is the call to the method in the main.cpp file:
#include "tombola.h"
#include <cstdlib>
#include <iostream>
#include <vector>
#include <ctime>
using namespace std;
int main () {
Tombola natale;
cout << natale.estrai();
}
When I compile the program everything goes fine, but when I execute the main I get a segmentation fault error which seems to be due to some sort of allocation error when trying to store the item inside the order vector, as reported by the debugger. Could someone explain to me how to solve the error and why the error occours? Thank you.
The reason of segmentation fault is in the constructor. You have to change for(int j=0;j<=x_max;j++) to for(int j=0;j<x_max;j++) in order not to cross the bounds of the array.
for(int j=0;j<x_max;j++) {
for (int k=0;k<y_max;k++) {
tabellone[j][k] = z;
z++;
}
}
However, there are also some minor issues in the code that are worth being mentioned
declaring default-initialized ord vector and assigning it to order is pointless because order is already default-initialized.(See member initializer list for more information).
using namespace std; in a header file is a terrible idea, because if you had a large codebase, and had multiple source files where you want to include that header, everywhere the using statement will be applied, which probably is not desired.
When an object is placed inside a vector, the vector makes a copy of the object, this means that any changes to the object does not change the object inside the vector. How do i make so any changes to the object also change the object inside the vector.
#include <iostream>
#include <vector>
using namespace std;
class objectClass {
public:
int x = 0;
};
vector<int> my_vector;
int main()
{
objectClass testObject;
vector<objectClass> my_vector = {testObject};
testObject.x = 5;
cout << my_vector[0].x;
}
//outputs 0
You can do this in two way
change the object from the vector like :
#include <iostream>
#include <vector>
using namespace std;
class objectClass {
public:
int x = 0;
};
vector<int> my_vector;
int main()
{
objectClass testObject;
vector<objectClass> my_vector = {testObject};
my_vector[0].x = 5;
cout << my_vector[0].x;
}
or you can do this by using pointers or reference, use a vector of pointers, where the vector will have the collections of objects references and thus changing the object from outside the vector also will change from inside the vector.
#include <iostream>
#include <vector>
using namespace std;
class objectClass {
public:
int x = 0;
};
int main()
{
objectClass testObject;
vector<objectClass*> my_vector = {&testObject};
testObject.x = 5;
cout << my_vector[0]->x;
}
One way of doing it would be having a vector of pointers instead, where each pointer points to some instance of objectClass:
#include <iostream>
#include <vector>
using namespace std;
class objectClass {
public:
int x = 0;
};
int main()
{
objectClass testObject;
vector<objectClass*> my_vector = {&testObject};
testObject.x = 5;
cout << my_vector[0]->x;
}
I'm programming a board game. When I call the constructor (with parameters) for the game, the program segfaults.
Main file:
#include <iostream>
#include "game.h"
using namespace std;
int main(){
int p_count = 2;
Game g(p_count);
//g.play();
}
Game Header:
#ifndef GAME_H_
#define GAME_H_
#include <iostream>
#include "board.h"
#include "player.h"
using namespace std;
class Game{
private:
Board b;
int moves, gamers;
Player players[10];
bool running;
public:
Game (int p_count);
void setup ();
void play ();
void report_score ();
bool in_mate (Player p);
bool in_check (Player p);
};
Game Constructor:
#include "game.h"
Game::Game(int p_count){
running = true;
moves = 0;
gamers = p_count;
}
Board header
#ifndef BOARD_H_
#define BOARD_H_
#include <iostream>
using namespace std;
class Piece;
class Board{
private:
static const int SIZE = 8;
Piece *board[SIZE][SIZE];
public:
Board ();
};
#endif /* BOARD_H_ */
Board constructor
#include "board.h"
#include "piece.h"
Board::Board(){
bool b = false;
for (int i=0; i<SIZE; i++){
for(int j=0; j<SIZE;j++){
board[i][j]->set_status(b);
}
}
}
Player header
#ifndef PLAYER_H_
#define PLAYER_H_
#include <iostream>
#include "board.h"
#include "piece.h"
using namespace std;
class Player{
private:
static const int NUM = 16;
Piece pieces[NUM];
int side;
public:
Player ();
Player (int p);
#endif
Player constructor
#include "player.h"
Player::Player(){
side = 0;
}
Piece header
#ifndef PIECE_H_
#define PIECE_H_
#include <iostream>
#include "board.h"
using namespace std;
class Board;
struct location{
int row;
int col;
};
class Piece{
private:
location pos_moves[50], loc;
char type;
bool status;
int moved, team;
public:
Piece ();
Piece (int piece_num, int bel);
void set_status (bool b);
};
#endif /* PIECE_H_ */
Piece implementation
#include "piece.h"
Piece::Piece(){
status = false;
team = 0;
moved = 0;
type = 'A';
}
void Piece::set_status(bool b){
status = b;
}
I call some functions from within the constructor that initialize the unused variables, but the program crashes regardless of whether or not they're included.
One problem that I see is that you have defined board as an array of pointers, not objects,
Piece *board[SIZE][SIZE];
and then you proceed to use board in Game::Game() as though board points to valid objects.
Board::Board(){
bool b = false;
for (int i=0; i<SIZE; i++){
for(int j=0; j<SIZE;j++){
// Problem.
// board[i][j] has not been initialized
// to point to any valid object.
board[i][j]->set_status(b);
}
}
}
You can resolve that by making board an array of objects.
Piece board[SIZE][SIZE];
or making sure that you allocate memory each element of the array before using them.
Board::Board(){
bool b = false;
for (int i=0; i<SIZE; i++){
for(int j=0; j<SIZE;j++){
// Allocate memory for the element
// of the array.
board[i][j] = new Piece;
board[i][j]->set_status(b);
}
}
}
I recommend using an array of objects. Then, you won't have to worry about dealing with memory allocation and deallocation. If you use an array of pointers, please read The Rule of Three.
board is a 2-d array of the pointer of Piece, you should new it before use it in Board's ctor:
Board::Board(){
bool b = false;
for (int i=0; i<SIZE; i++){
for(int j=0; j<SIZE;j++){
board[i][j] = new Piece; // add it here
board[i][j]->set_status(b);
}
}
}
BTW, don't forget to delete the pointers, maybe in Board's dtor.
So here is the main where i'm trying to call the array by a pointer:
#include <iostream>
#include "Lottery.h"
#include "Player.h"
#include "LotteryData.h"
using namespace std;
int main()
{
Player player;
Lottery random;
LotteryData data;
player.Input();
random.setRandomNumber();
data.PassInfo(int (&Numbers)[6][6]);
}
Apparently "Numbers" is undefined even though the header is included, here's the header and .cpp files relating to it.
LotteryData.h
#pragma once
#include <iostream>
#include <fstream>
#include "Lottery.h"
#include "Player.h"
using namespace std;
class LotteryData
{
private:
public:
LotteryData();
~LotteryData();
void PassInfo(int (&Numbers)[6][6]);
};
LotteryData.cpp
#include <iostream>
#include <fstream>
#include "LotteryData.h"
using namespace std;
LotteryData::LotteryData()
{
}
LotteryData::~LotteryData()
{
}
void LotteryData::PassInfo(int (&Numbers)[6][6])
{
int* ptr;
FILE *Numfile;
Numfile = fopen("C:/Num.txt", "wb");
ptr = &Numbers[6][6];
for (int i=0; i<36; i++)
{
fwrite(ptr, sizeof(int), 36*36, Numfile);
}
fclose(Numfile);
//ofstream out("Numbers.txt");
}
Everything seems fine, I'm puzzled why the reference in the main says the array is undefined, any ideas?
edit: Apologies, missed some bits
Player.h
#pragma once
#include <iostream>
#include <fstream>
using namespace std;
class Player
{
private:
public:
Player();
~Player();
void Input();
int Numbers[6][6];
};
Player.cpp
#include <iostream>
#include <fstream>
#include "Player.h"
using namespace std;
Player::Player()
{
}
Player::~Player()
{
}
void Player::Input()
{
int num(0);
int duplicate = 0;
int game = 0;
int NumberofGames = 0;
cout<<"How many games do you want to play for this weeks draw?"<<endl;
cin>>NumberofGames;
if (NumberofGames>6)
{
cout<<"Please enter an amount between 1 and 6"<<endl;
cin>>NumberofGames;
}
do
{
for (int i=0;i<6;i++)
{
cout<<"Enter Number "<< (i+1) <<endl;
cin>>num;
if (num > 0 && num <67)
{
Numbers[game][i]= num;
}
else
{
cout <<"Please enter number between 1 and 66"<<endl;
i = i-1;
}
}
game = game + 1;
NumberofGames = NumberofGames - 1;
}
while (NumberofGames=0);
}
void PassInfo(int (&Numbers)[6][6]);
That line does not declare an array - it declares a function. You have no declaration for an array in your class (in fact, you have no data members declared in your class at all).
If you want to declare a member array, you need to modify your class definition:
class LotteryData
{
private:
int Numbers[6][6]; // this declares an array
public:
LotteryData();
~LotteryData();
void PassInfo(int (&arr)[6][6]); // this is still a function declaration
};
Just because you made a function's parameter be named Numbers doesn't magically mean that your program has an array called Numbers declared in it.
So a Player has an array called "Numbers".
Then you would use it like this:
data.PassInfo(player.Numbers);
In your main() function,
data.PassInfo(int (&Numbers)[6][6]);
This is wrong. You should simply pass a reference to 2D array.
int (&Numbers)[6][6];
data.PassInfo(Numbers);
I have simple class in a header file: a.hh
#ifndef a_hh
#define a_hh
class a
{
public:
int i;
a()
{
i = 0;
}
};
#endif
Then i have a file:b.cc
#include <iostream>
#include "a.hh"
using namespace std;
int main(int argc, char** argv)
{
a obj;
obj.i = 10;
cout << obj.i << endl;
return 0;
}
>
Till this point everything is fine.
I compile the code and it compiles fine.
But as soon as i add a vector in the class:
#ifndef a_hh
#define a_hh
class a
{
public:
int i;
vector < int > x;
a()
{
i = 0;
}
};
#endif
I get a compilation error as below:
> CC b.cc
"a.hh", line 7: Error: A class template name was expected instead of vector.
1 Error(s) detected.
What is the problem with declaring a vector here as a member?
You need to #include <vector> and use the qualified name std::vector<int> x;:
#ifndef a_hh
#define a_hh
#include <vector>
class a{
public:
int i;
std::vector<int> x;
a() // or using initializer list: a() : i(0) {}
{
i=0;
}
};
#endif
Other points:
(as commented by EitanT) I removed the additional qualification a:: on the constructor
have a read of Why is "using namespace std" considered bad practice?
declaring a vector as a class member:
#include <iostream>
#include <vector>
using namespace std;
class class_object
{
public:
class_object() : vector_class_member() {};
void class_object::add_element(int a)
{
vector_class_member.push_back(a);
}
void class_object::get_element()
{
for(int x=0; x<vector_class_member.size(); x++)
{
cout<<vector_class_member[x]<<" \n";
};
cout<<" \n";
}
private:
vector<int> vector_class_member;
vector<int>::iterator Iter;
};
int main()
{
class_object class_object_instance;
class_object_instance.add_element(3);
class_object_instance.add_element(6);
class_object_instance.add_element(9);
class_object_instance.get_element();
return 0;
}
1.You need to #include <vector> and using namespace std, then a.hh just like below:
#ifndef a_hh
#define a_hh
#include <vector>
using namespace std;
class a
{
public:
int i;
vector <int> x;
a()
{
i = 0;
}
};
#endif
2. If you don't want to only use std namespace in all your code, you can specified the namespace before type, just like std::vector<int> x;