C++, How to call a child method in the parent class - c++

I have two classes in my project:
Style
Line
In which, Line is the child of Style, so Line inherits from Style.
I need that when I call a method of the class Style (the parent) from Line (the child), the method of Style calls a method of the child, for your better understanding here is the code:
Line calls the Style function --> Style calls the Line function
Style.h:
#pragma once
class Style
{
public:
void set_size(int width, int height);
protected:
int width, height;
};
Style.cpp:
#include "Style.h"
void Style::set_size(int width, int height)
{
Style::width = width;
Style::height = height;
}
Line.h:
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : public Style
{
public:
void draw();
vector <vector<char>> matrix;
};
Line.cpp:
#include "Line.h"
void Line::draw()
{
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::height; i++)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
Main.cpp:
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10);
}
Obviously, this code for now does nothing much, it only modifies Style variables.
What I expect is that when I call set_size(), in addition to changing the value of the variables width and height, it will also change the size of the matrix
I don't know how to do what I said before.
I don't even know if it is a good method that Line is a child of Style, in any case other solutions that do not include inheritance are welcome.
Thanks in advance.

You need virtual functions, it would seem that set_size is the one that should be virtual, but this is not the only way to do it.
class Style
{
public:
virtual void set_size(int width, int height);
virtual ~Style() {}
protected:
int width, height;
};
class Line : public Style
{
public:
void draw();
virtual void set_size(int width, int height)
{
Style::set_size(width, height);
... // some code to resize matrix
}
vector <vector<char>> matrix;
};
But I question if this is good design, Style should be an attribute of Line (i.e. a member variable). Inheritance doesn't seem appropriate here, which is why you are struggling to write the code.

I tried to have implementation and declaration in the same file. but you can structure it as you may feel good for your project.
#include <iostream>
#include <vector>
using namespace std;
class Line;
class Style
{
public:
void set_size(int width, int height){
w = width;
h = height;
}
void print(){
cout << w << ", " << h << endl;
}
friend class Line;
protected:
int w, h;
};
class Line : public Style
{
public:
void draw(){
vector <char> row;
int i, j;
for (i = 0; i < w; i++)
{
row.clear();
for (j = 0; j < h; i++)
{
row.push_back('-');
}
matrix.push_back(row);
}
}
vector<vector<char>> matrix;
};
int main()
{
Line line;
line.set_size(10, 10);
line.print();
line.set_size(20, 20);
line.print();
}

We can just overload set_size within Line and call the other set_size from there and also the draw function to recreate the matrix.
This solution provides simple static polymorphism, that means a Line cannot be assigned to a Style - you probably do not need this? So the compiler always statically at compile-time knows, which class an object really is and can call the correct member function. No virtual member functions are needed.
There also were bugs in the draw function, which I corrected below.
The changes to your code are marked with a comment in the following.
// Line.h
#pragma once
#include "Style.h"
#include <vector>
using namespace std;
class Line : private Style // use private inheritance for static polymorphism
{
public:
void draw();
void set_size(int width, int height); // overload set_size (override only for virtual functions)
vector <vector<char>> matrix;
};
// Line.cpp
#include "Line.h"
void Line::set_size(int width, int height)
{
Style::set_size(width, height); // call set_size() function of style
draw(); // draw() to set matrix to new size
}
void Line::draw()
{
Line::matrix.clear(); // clear matrix, if draw() is called more than once
vector <char> row;
int i, j;
for (i = 0; i < Line::height; i++)
{
row.clear();
for (j = 0; j < Line::width; j++) // use Line::width and j++ (there were bugs)
{
row.push_back('-');
}
Line::matrix.push_back(row);
}
}
// Main.cpp
#include <iostream>
#include "Line.h"
using namespace std;
int main()
{
Line line;
line.set_size(10, 10); // calls the enhanced Line::set_size
// The following compilation errors (when the comments are removed) are good, as they prevent wrong usage of the current class definitions
// Style style = line; // would give error, as we have private inheritance and want to prevent 'slicing' and the calling of the wrong member functions; if a Line should be able to be assigned to a Style, you need public dynamic inheritance and virtual functions, as provided in other answers. If you do not need to assign a Line to a Style, use the simpler implementation from this answer.
// Style* stylepointer = &line; // also would give an error
}
Optionally draw() and matrix can be made private in Line.
If you need to call functions (other than set_size) of Style directly, you can use public inheritance, but make all constructors (including default/copy/move) of Style protected, so that only children like Line can call them. This would also prevent assignments of Line to Style.

EDIT: I'm completely changing the original answer since the question was modified too. If I get it right, you would like line.set_size(...) to call first the parent method and then to update the matrix. You cannot do that, because only one method will be called, and not both of them what you could do is add a set_size method for Line that calls Style's one.
line.h should be changed like this:
class Line : public Style
{
public:
void draw();
void set_size(int width, int height);
vector<vector<char>> matrix;
};
and you should append this to line.cpp:
void Line::set_size(int width, int height)
{
// call parent method
Style::set_size(width, height);
// now update matrix
int i, j;
matrix.resize(height);
for (auto &row : matrix)
{
row.resize(width);
}
}
Hope it helps!

Base function must be virtual for runtime inheritance.
as follows example
class base {
public:
virtual void print()
{
cout << "print base class\n";
}
void show()
{
cout << "show base class\n";
}
};
class derived : public base {
public:
void print()
{
cout << "print derived class\n";
}
void show()
{
cout << "show derived class\n";
}
};
int main()
{
base *bptr;
derived d;
bptr = &d;
// Virtual function, binded at runtime
bptr->print();
// Non-virtual function, binded at compile time
bptr->show();
return 0;
}

Related

How to use member of one class in another class constructor

I have a class:
class Cave
{
private:
int no_of_rooms;
public:
vector<int>rooms;
Cave(int r);
Cave(){};
};
The constructor of Cave fills the vector rooms with random integers:
Cave::Cave(int r)
:no_of_rooms{ r }
{
int i = 0;
while (i<no_of_rooms)
{
rooms.push_back(randint(1, no_of_rooms));
++i;
}
}
I create another class:
class Player : public Cave
{
public:
Player(int *plyr)
:p_ptr{ plyr }
{
plyr = &rooms[0];
}
private:
int* p_ptr = nullptr;
};
This Player class seems to be a mess. I am trying to get access to the same rooms vector filled up by the Cave constructor.
I think you really should encapsulate Cave and not inherit from it. Try this.
cave.h
#include <vector>
#include <random>
class Cave
{
private:
int no_of_rooms;
public:
std::vector<int>rooms;
Cave(int r);
Cave(){};
};
inline int randint(int min, int max)
{
std::random_device device;
std::mt19937 engine(device());
std::uniform_int_distribution<int> dist(min, max);
return dist(engine);
}
cave.cpp
#include "cave.h"
Cave::Cave(int r)
:no_of_rooms{ r }
{
int i = 0;
while (i<no_of_rooms)
{
rooms.push_back(randint(1, no_of_rooms));
++i;
}
}
player.h
#include "cave.h"
class Player// : public Cave
{
public:
Player(int *plyr)
:p_ptr{ plyr }
{
cave = Cave(*plyr);
plyr = &cave.rooms[0];
}
private:
Cave cave;
int* p_ptr = nullptr;
};
I tried it using
#include "player.h"
int main(int argc, char* argv[])
{
int player_count = 2;
Player p(&player_count);
}
Also, I am not sure the unnecessary use of pointers in some of your code.
You may have a typo:
plyr = &rooms[0];
This sets the function argument, not the member.
You meant p_ptr = &rooms[0];?
But then why have a function argument at all. This makes no sense.
Unfortunately, you did not get around to telling us what you want to do, or what you want these classes to do, or what input you need to provide to the classes. So I cannot answer any further.

error: using-declaration for non-member at class scope using std::cout

I downloaded a c++ project and was able to compile it using a makefile generated by cmake.
However when I try to add my own series of .h files in one of the .hh files of the project I start to get a million of errors, one of them being:
error: using-declaration for non-member at class scope
using std::cout;
When the .h file that contains
using std::cout is used elsewhere it works, but when added to this project it gives this error.
What can be the problem?
using std::cout;
using std::endl;
class TextManager : public FileManager {
public:
TextManager (const char * filename);
void scanFile (Image &image, Scene &scene);
void scanObjectModel (Image &image, Scene &scene);
void getImageData (Image &image);
void getMaterialData (Scene &scene);
void getLightData (Scene &scene);
void getSphereData (Scene &scene);
void getPlaneData (Scene &scene);
void getTriangleData (Scene &scene);
int getLineValue (int size);
void getLineValue2 (float (&lineNumbers) [10], Scene &scene, int &lineNumbersIndex);
void getVerticesValues (int initPos, Scene &scene);
private:
std::string line;
float fractionaryTenPowers [6];
};
Problem solved. Was the lack of a bracket to close the declaration of one of the classes that was causing it.
The error means you've done this:
struct Foo {
using std::cout;
...
};
That's not valid C++, in a class body you can only add a using-declaration for members of base classes, not arbitrary names.
You can only add using std::cout at namespace scope or inside a function body.
You can put it in the class as long as you put it under the public or private sections.
#include <iostream>
namespace CoolNamespace
{
struct AnotherReallyLongClassName
{
int a = 75;
};
struct SomeReallyLongClassName
{
int a = 42;
};
} // namespace CoolNamespace
class Widget
{
// You can't do this though!
// using ShorterName = CoolNamespace::SomeReallyLongClassName;
public:
// You can use a using statement inside of a class!
using ShorterName = CoolNamespace::SomeReallyLongClassName;
ShorterName foo;
int get_another_name()
{
return bar.a;
}
private:
// You can do it here also!
using AnotherName = CoolNamespace::AnotherReallyLongClassName;
AnotherName bar;
};
int main()
{
Widget widget;
std::cout << widget.foo.a << std::endl;
// Also, if you can reference public using statements from the class definition.
Widget::ShorterName thing;
std::cout << thing.a << std::endl;
// But you can't do this because it's private.
// Widget::AnotherName name;
return 0;
}
Indeed, check if you have one open bracket in one of the member functions in the class declaration.
I did this in .h file;
class foo{
void cat();
void bar{
void dog();
}
in .cc file I defined the member functions
void foo::cat(){
std::cout<<"This is cat"<<std::endl;
}
void foo::bar(){
std::cout<<"hello"<<std::endl;
}
void foo::dog(){
std::cout<<"meow"<<std::endl;
}
But notice I used { instead of; for member function bar in .h file. That's causing the error. (At least for me).

Declaring vector size in a class

I am supposed to write a program that simulates a dice(6 faced) roll 6000 times and stores the results in a vector. For example if the dice roll returns 1, I would do something like frequency.at(0)++. Since the size of the vector is gonna be fixed, and I would also need to able to access each element freely, I was wondering if there was anyway to declare the size of the vector using a default constructor or something. This is what I currently have but I get a "too many arguments in function call" and "expression must have class type" error. Maybe what I'm trying to do is not possible, I don't know, but just looking for some help. Thanks.
My header file:
#ifndef AHISTOGRAM_H
#define AHISTOGRAM_H
class aHistogram
{
public:
aHistogram();
~aHistogram();
void update(int face);
void display(int maxLengthOfLine);
void clear() const;
int count(int face);
private:
vector<int> numRolls();
int numx, m, j;
};
#endif
aHistogram.cpp:
#include <iostream>
#include <cstdlib>
#include <vector>
#include "aHistogram.h"
using namespace std;
aHistogram::aHistogram()
{
numRolls(6);
numx, m, j = 0;
}
aHistogram::~aHistogram()
{
}
void aHistogram::update(int face)
{
numRolls.at(face - 1)++;
return;
}
This is what the constructor's initializer list is for:
aHistogram::aHistogram(): numRolls(6), numx(0), m(0), j(0) // constructor parameters here
{
// numRolls(6);
// numx m, j = 0;
}
Also the declaration of your vector is wrong in your class definition:
class aHistogram
{
public:
aHistogram();
~aHistogram();
void update(int face);
void display(int maxLengthOfLine);
void clear() const;
int count(int face);
private:
// vector<int> numRolls(); // this is declaring a function!
vector<int> numRolls; // USE THIS!!
int numx, m, j;
};
IF the size of the "vector" is fixed, then using std::array is most certainly a better option, unless of course, you are using an ancient compiler which doesn't support C++11.
Go through the above link on cppreference.com. For most part, it is just like an "old fashioned" array, but it also comes with benefits such as bounds checking (if you use at() instead of operator[]), ability to iterate through elements (begin(), end(), etc.), and many other "benefits" of std::vector.
Have a look at this:
#include <iostream>
#include <array>
using namespace std;
class aHistogram {
public:
aHistogram() : numRolls{0, 0, 0, 0, 0, 0} {}
int count(int face) {
return numRolls.at(face - 1);
}
void update(int face) {
numRolls.at(face - 1)++;
}
private:
array<int, 7> numRolls;
};
int main() {
aHistogram ah;
ah.update(1);
ah.update(2);
ah.update(1);
cout << "Count[1]: " << ah.count(1) << " Count[2]: " << ah.count(2) << endl;
}

error C2280: attempting to reference a deleted function

I'm new to game development and very new to c++, but I've started developing a little Arkanoid game. I've had it running previously, but after refactoring (introducing the ArkanoidGame class) it doesnt compile and I cannot figure out why.
The error I'm getting is:
d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\main.cpp(14): error C2280:
'ArkanoidGame::ArkanoidGame(void)' : attempting to reference a deleted function
d:\dropbox\development\gamedev\c++\arkanoid\arkanoid\arkanoidgame.h(25) :
compiler has generated 'ArkanoidGame::ArkanoidGame' here
I simply dont understand what this means and have no idea what to do to fix it.
I've included the classes in question:
Main.cpp:
#include "ArkanoidGame.h"
int main() {
ArkanoidGame game;
game.init(800, 600);
while (game.isRunning()) {
game.checkInput();
game.checkCollisions();
game.draw();
}
return 0;
}
Arkanoid.h:
#include "Ball.h"
#include "Pad.h"
#include <SFML/Graphics.hpp>
#include <stdarg.h>
#include <memory>
class ArkanoidGame
{
private:
bool running;
public:
void ArkanoidGame::init(int, int);
bool ArkanoidGame::isRunning();
void ArkanoidGame::checkCollisions();
void ArkanoidGame::checkInput();
void ArkanoidGame::update();
void ArkanoidGame::draw();
sf::RenderWindow* window;
Pad pad;
Ball ball;
};
ArkanoidGame.cpp:
#include "ArkanoidGame.h"
void ArkanoidGame::init(int windowWidth, int windowHeight) {
window = new sf::RenderWindow(sf::VideoMode(windowWidth, windowHeight), "Arkanoid!");
window->setFramerateLimit(60);
ArkanoidGame::running = true;
//Init pad
pad = Pad((float)(windowWidth / 2), (float)(windowHeight - 50));
//Init ball
ball = Ball(0.f, 0.f);
}
template<class T1, class T2> bool intersect(T1& mA, T2& mB) {
return mA.right() >= mB.left() && mA.left() <= mB.right()
&& mA.bottom() >= mB.top() && mA.top() <= mB.bottom();
}
void ArkanoidGame::checkCollisions() {
if (!intersect(pad, ball)) return;
ball.velocity.y = -ball.ballVelocity;
if (ball.x() < pad.x()) {
ball.velocity.x = -ball.ballVelocity;
}
else {
ball.velocity.x = ball.ballVelocity;
}
}
void ArkanoidGame::update() {
//Update positions
pad.update(window->getSize().x);
ball.update(window->getSize().x, window->getSize().y);
}
void ArkanoidGame::draw() {
window->clear(Color::Black);
window->draw(pad.getShape());
window->draw(ball.getShape());
window->display();
}
void ArkanoidGame::checkInput() {
if (Keyboard::isKeyPressed(Keyboard::Key::Escape)) {
running = false;
}
}
bool ArkanoidGame::isRunning() {
return running;
}
Presumably, either Pad or Ball (or both) has no default constructor; therefore one can't be generated for a class that contains them. They must be initialised using one of their declared constructors.
The best solution is to remove your weird init function, and replace it with a constructor:
ArkanoidGame(int windowWidth, int windowHeight) :
running(true),
window(new ...),
Pad(windowWidth / 2, windowHeight - 50),
Ball(0,0)
{
window->setFramerateLimit(60);
}
int main() {
ArkanoidGame game(800, 600);
// ...
}
If you really want a two-stage initialisation dance for some reason, then you'll need to provide default constructors for both Pad and Ball. I wouldn't recommend that though; there's less scope for errors if an object can't be created in an invalid state.
I think that the problem is that either class Pad or class Ball has no the default constructor ( you have two dtat members of these classes in the class definition of ArkanoidGame: Pad pad; and Ball ball;)
. In this case the compiler defined the default constructor of class ArkanoidGame as deleted (otherwise it will be ill-formed). However in the first line of main
ArkanoidGame game;
you try to call the default constructor of class ArkanoidGame.
Take also into account that declarations of member functions shall have unqualified names in the class definition.
So for example this declaration
void ArkanoidGame::init(int, int);
is invalid. Shall be
void init(int, int);
You should provide a constructor for ArkanoidGame. In Arkanoid.h:
ArkanoidGame ();
In Arkanoid.cpp:
ArkanoidGame::ArkanoidGame ()
{
// it is better to initialize members in the constructor,
// although not strictlynecessary
running = false;
}

C++ Function Pointers using class T [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am working on my own GUI framework using C++ and OpenGL. My experience in both is small as this is my first project using them.
In the framework I have created a window, which renders the design of the window, and then any objects that have been added to the window as a child.
I then create the window using a new class called MainMenu that inherits from my window class, I then add a new button to the MainMenu
Using:
button->SetOnClick(&MainMenu::button_Click, this);
I then add a pointer to the function, as well as the instance of the class to the buttons 'SetOnClick' method - Therefore if that button is clicked a method within the MainMenu will run.
This works great at the moment, however my issue now is that I want to add a new window called Settings, which will also inherit from the Window class
Therefore I need to make the function pointer in my button class work for any number of classes (all of type Window)
Here is the code that is currently working - but for only the MainMenu (Please note that I have stripped out a lot of methods that do not relate to the question to make it easier to read)
Window.h:
class Window
{
private:
void Initialize(WindowManager* manager, int width, int height);
public:
Window(WindowManager* manager);
Window(WindowManager* manager, int width, int height);
~Window(void);
void Render();
bool MouseMove(int x, int y);
bool MouseLBDown(int x, int y);
Children* Child() { return m_children; };
MainMenu.h:
class MainMenu : public ObjWindow
{
private:
void Initialize();
public:
MainMenu(WindowManager* manager, int width, int height) : Window(manager, width, height)
{
Initialize();
};
MainMenu(WindowManager* manager) : Window(manager)
{
Initialize();
};
~MainMenu(void);
void button_Click();
MainMenu.cpp:
void MainMenu::Initialize()
{
Button* button = new Button(Vector2D(100, -400), 100, 50);
Child()->Add(button);
button->SetText("Click Me!");
button->SetOnClick(&MainMenu::button_Click, this);
}
void MainMenu::button_Click()
{
//Do some button code
}
Button.h:
class Button
{
typedef void (MainMenu::*Function)();
Function m_onClickFunction;
MainMenu* m_window;
public:
Button(Vector2D position, int width, int height);
~Button(void);
void SetText(std::string);
std::string GetText();
void Render();
bool MouseMove(int x, int y);
bool MouseLBDown(int x, int y);
void SetOnClick(Function, MainMenu*);
Button.cpp:
Button::Button(Vector2D position, int width, int height)
{
m_onClickFunction = NULL;
}
Button::~Button(void)
{
}
bool Button::MouseMove(int x, int y)
{
return true;
}
bool Button::MouseLBDown(int x, int y)
{
if (m_body->Intercepts(x,y))
{
if (m_onClickFunction != NULL)
{
(m_window->*m_onClickFunction)();
}
}
return true;
}
void Button::SetOnClick(Function function, MainMenu* window)
{
m_onClickFunction = function;
m_window = window;
}
From researching around the internet it seems that I need to use a template so that I can handle the class as a type, I have tried fitting this in to my code, but so far I nothing has worked.
Please note that I am also new to asking question on stackoverflow, so if I am missing anything important please let me know
You need to either create a template of the Button class - in your case it would look like this:
template <typename myType>
class Button{
typedef void (myType::*Function)();
Function m_onClickFunction;
myType* m_window;
public:
...
void SetOnClick(Function, myType*);
}
And use it like this:
Button<MainMenu> button;
button->SetOnClick(&MainMenu::button_Click, this);
...or create a delegate class. There are plenty of examples about delegates in C++, if you search for them.
But I'm not so sure if you wan't to stick with passing pointers to functions. You might be better off always calling the same method of derived classes, and using the virtual keyword.
Like this:
class Window{
public:
virtual void button_Click(){};
};
class someDerivedWindow: public Window{
public:
void button_Click(){};
};
and inside the button class just calling:
m_window->button_Click();
You could work and implement your own library to do member function pointers, depending on what the goal of your project is. It is fairly complicated though, and requires a rather deep understanding of C++.
However, you can also use boost::function combined with std::bind or boost:bind, to achieve what you want to do.
If you have
struct X {
int foo(int);
};
You can use:
boost::function1<int, int> f;
X x;
f = std::bind1st(
std::mem_fun(&X::foo), &x);
f(5); // Call x.foo(5)
This example is taken directly from the boost::function documentation - http://www.boost.org/doc/libs/1_55_0/doc/html/function.html
If using C++11:
#include <iostream>
#include <functional>
#include <vector>
#include <cstdlib>
#include <algorithm>
#include <ctime>
using namespace std;
int foo1()
{
return 0;
}
int foo2()
{
return 1;
}
int main()
{
function<int()> f1 = foo1;
function<int()> f2 = foo2;
//do some magic
srand(time(0));
function<function<int()>()> generator = [&]()
{
if(rand() % 2 == 0)
return foo1;
else
return foo2;
};
vector<function<int()>> vec(100);
generate(vec.begin(),vec.end(),generator);
for(auto elem: vec)
cout << elem() << endl;
return 0;
}