Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
I have tried to make some sort of card game here but the classes for the holder / cardpile don't give away right things to the reciver/player and I don't know how to sort this out.
Here is the program:
#include <iostream>
using namespace std;
class subclass // like a card
{
public:
subclass();
subclass(int x);
int nummer;
int getnummer();
};
subclass::subclass():nummer(0){}
subclass::subclass(int x):nummer(x){}
int subclass::getnummer()
{
return nummer;
}
holder class:
class holder // like a cardpile
{
public:
holder();
subclass cardpile[2];
subclass* pile; // a cardpile which has 2 cards, with nummber 1 and 2.
subclass* getsubclass(int i); // take first or second card.
};
holder::holder()
{
subclass first(1*3);
subclass second(2*3);
pile=cardpile;
pile=&first;
pile++;
pile=&second;
pile--;
}
subclass* holder::getsubclass(int i) //1 eller 2.
{
return pile+i;
}
reciver class/ the player
class reciver // like a player
{
public:
subclass part_of_holder;
reciver();
void getsubclass( subclass* in); // give this card to player from this pointer
void showinside(); // what card do player have
};
reciver::reciver():part_of_holder(){}
void reciver::getsubclass( subclass* in)
{
part_of_holder=*in;
}
void reciver::showinside() // what card do player have
{
cout<< part_of_holder.getnummer();
}
and the main
int main()
{
holder cardpile;
reciver player;
cout << "first card should be 1*3 and it is : " ;
player.getsubclass(cardpile.getsubclass(0));
player.showinside();
cout << endl <<"first card should be 2*3 and it is : " ;
player.getsubclass(cardpile.getsubclass(1));
player.showinside();
return 0;
}
In the end all I get is nonsence
holder::holder()
{
subclass first(1*3);
subclass second(2*3);
pile=cardpile;
pile=&first; // WRONG
pile++;
pile=&second; // WRONG
pile--;
}
The two lines above dont do what I suspect you think they do.
If you are trying to assign in the cardpile you would need something more like this:
cardpile[0] = first or *pile = first.
Sadly they wont work, since you dont have copy constructors. You also dont have any way to set a subclass's nummer field once constructed, so you are slightly doomed.
Add a setter function to the get instruction, and you could write this:
cardpile[0].setnummer(first.getnummer());
This is not going to work
holder::holder()
{
subclass first(1*3); // create temporary
subclass second(2*3); // create another temoporary
pile=cardpile; // assign member pointer to another member!!!
pile=&first; // assign member pointer to temporary
pile++;
pile=&second; // assign member pointer to temporary
pile--;
}
// member pointer pile points to object that no longer exists!!!
Basically once you create an instance of holder its internal pile pointer points to an object that no longer exists and that alone makes your class unstable because your getsubclass method returns an offset of this pointer - thus any attempt to dereference it will likely segfault.
In all honesty you would be better to start off again from scratch but a way of ensuring that you assign these temporaries to your member array would be
cardpile[0] = subclass(1*3);
cardpile[1] = subclass(2*3);
pile = cardpile;
however, the way this code is written is not a good design and I would advise starting from scratch when your grasp of C++ is better.
Related
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 11 months ago.
Improve this question
So, I know a vector object can be declared and initialized like this:
// Nothing new here. I know <int> is a template
// and how to implement it:
vector <int> vect{ 10, 20, 30 };
I assume that the vector object has inside an array of values, and the functions of that class (like push_back() for example) manage it. I would like and have been trying to implement something like that in a class of my own, without success. Would be interesting being able to understand how it's done! Did many "experiments" but none worked.
// Random named class:
class A_Class
{
private:
// A pointer for the type I want:
int *A_pointer_To_int;
public:
// Trying to accept the input values between
// brackets and putting them inside a temp array:
A_Class(int Input_Array[]) {}
};
int main()
{
// trying to create the object like in the vector class.
// Returns error "No instance of constructor matches the argument list":
A_Class My_Object{1,2,3}
return 0;
}
In a function parameter, int Input_Array[] is just syntax sugar for a decayed pointer int* Input_Array, which does not provide any information about any array that may be passed in to it.
For what you are attempting, you need to accept a std::initializer_list instead, eg:
#include <initializer_list>
#include <algorithm>
// Random named class:
class A_Class
{
private:
// A pointer for the type I want:
int *A_pointer_To_int;
// the number of values in the array:
size_t size;
public:
A_Class(std::initializer_list<int> Input_Values) {
size = Input_Values.size();
A_pointer_To_int = new int[size];
std::copy(Input_Values.begin(), Input_Values.end(), A_pointer_To_int);
}
~A_Class() {
delete[] A_pointer_To_int;
}
};
int main()
{
A_Class My_Object{1,2,3}; // works now
return 0;
}
Online Demo
I have two classes Instructor and Game.
Instructor.h
class Instructor
{
int instrID;
public:
Instructor();
void showGameStatus();
int createGame();
vector<int> createGames(int numberOfGames);
};
Game.h:
class Game {
private:
int gID;
int instrID;
int pFactID;
public:
Game() { // default constructor
gID = 0;
instrID = 0;
pFactID = 0;
};
These are in Instructor.cpp
void Instructor::showGameStatus()
{
}
int Instructor::createGame()
{
Game g;
}
CreateGame() initializes a game. I want that upon calling showGameStatus() I can print out all properties (eg gId, InstrId) of the Game g that initialized earlier etc.
Is it possible to access the properties of Game g that in another method?
This should do it. Class Instructor should inherit class Game:
class Instructor::public Game{
your code here
}
The short answer is: No.
The longer answer is this: If I understand correctly, what you want to accomplish, the problem is that the object g of type Game is held by a local variable inside the scope of your Instructor::createGame member function. Once that function is "done", i.e. the local scope ends, the object, which has automatic storage will be destroyed. It's gone. I don't know what the int means that you return, but no matter what it does, it doesn't hold an object of type Game.
Now, you probably want your createGame to return some type of handle to an actual Game object. Depending on your specific setting, it is your job to choose how to pass such an object around. For example, one way might be this:
Game Instructor::createGame() const { // 1
Game g;
// do stuff with g, perhaps?
return g;
}
Another might be:
std::unique_ptr<Game> Instructor::createGame() const { // 2
auto gptr = std::make_unique<Game>();
// do stuff with gptr, perhaps?
return gptr;
}
Or yet another:
std::size_t Instructor::createGame() { // 3
// Instructor has a member std::vector<Game> games
games.emplace_back();
// do stuff with games.back()
return games.size()-1;
}
There are countless other ways to pass the object around.
No matter what you choose you have to pass something to identify which Game object you are talking about back into your showGameStatus function, if you plan to have more than one Game object flying around (I assume you do).
auto some_handle = instructor.createGame();
// ... later ...
instructor.showGameStatus(some_handle);
This all holds true, if you want more than one object. Otherwise you might want to just add the object as a member of your Instructor type:
class Instructor {
private:
Game game;
public:
Instructor() : game() {}
// no createGame function, it is superfluous
void showGameStatus() const {
game.some_output_function();
}
};
Just inherit the Instructor Class into the Game Class and do your work...
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
I'm working on optimizing my current CLI project. When looking through the code and debugging I've noticed that I haven't released some dynamically allocated memory in a class. Here's how my code looks:
"Coordinates.h"
#pragma once
#include <Windows.h>
#define LENGTH 40
#define WIDTH 15
struct Coordinate
{
int x = 1;
int y = 1;
};
"Laser.h"
#pragma once
#include "Coordinates.h"
class Laser
{
private:
Coordinate* initCoord;
char icon;
public:
Laser(int x, int y);
char getIcon() const;
Coordinate* getCoord();
void move();
};
"Laser.cpp"
#include "Laser.h"
Laser::Laser(int x, int y)
{
initCoord = new Coordinate;
initCoord->x = x;
initCoord->y = y;
icon = '~';
}
char Laser::getIcon() const { return icon; }
Coordinate* Laser::getCoord() { return initCoord; }
void Laser::move()
{
++initCoord->x;
}
I've tried adding a destructor (declaring it in the header file first of course) which clears up the memory allocated for initCoord which looked something like this:
Laser::~Laser()
{
if(initCoord != nullpr) delete initCoord;
}
After adding that it caused a run-time error. "ProgramName.exe has stopped working..." Objects of this class are stored in a simple vector which gets cleared at one time of the program. The problem is that the crash happens before it even reaches the lasers.clear() line. I honestly have no idea why this crash is happening and would appreciate some help. Thank you! :)
If you consider this code
int main() {
Laser one(0,0);
{
Laser two = one;
cout << two.getCoord()->x << endl;
}
return 0;
}
What do you expect to be written?
"0"
which mean that the coordinate points to the same structure as one which again means that when the first } happens and two gets destroyed one doesn't have a valid coordinate any more.
When you have a pointer member you need to either disable copying/assigning or implement them.
In this case you could also have been rescued if you had used a std::unique_ptr instead of the raw pointer (which also saves you the delete).
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 6 years ago.
Improve this question
I'm making a Pacman game where I have several classes which include, Board (Does all the job through its pointer), Chase (which is inherited from Ghosts). Now I've made a virtual function of 'chase' in Ghosts which is overridden in its children i.e Chase class. Also, in the Board I've Ghosts array of Objects (which is of size four obviously). I have also made a 'chase' function in Board which actually calls the first ghost's chase, which will in turn (this is where I'm confused) go into its child's class to be accessed. Kindly help me with this because it's not working as I want it to.
I would like to give a thorough explanation here:
1) Through Board's class pointer I do almost all the work. This means that my Ghosts class is COMPOSED in my Board class. Board has a function of chase, in which a GHOST object calls its VIRTUAL chase function.
2) Chase CLASS is derived from Ghost class and contains a chase function as well.
I have to call this Chase CLASS chase function through the pointer of board.
Ghosts(int x = 0, int y=0)
{
protected:
x_pos = x;
y_pos = y;
}
virtual void chase(char bD)
{
}
class Chase : public Ghosts
{
public:
Chase() :Ghosts(){}
void chase(char bD)
{
// access x_pos;
// access y_pos;
}
class Board {
private:
Ghosts G[4];
public:
void Chase(char bD)
{
G[0].chase(bD);
}
your problem resides with understanding how to use polymorphism,
polymorphism works on reference and on pointers in your case it's neither.
let's explore it:
class A {
public:
virtual ~A() {};
virtual void chase(char bd) { cout << "A chases : "<< bd << endl; }
};
class B : public A {
public:
void chase(char bd) override { cout << "B chases : " << bd << endl; }
};
in main or w/e:
A a, *aptr;
B b;
a.chase('s');
b.chase('s');
aptr = &b;
aptr->chase('s');
a = b;
a.chase('s');
A &ref = b;
ref.chase('s');
... will yeild:
A chases : s
B chases : s
B chases : s
A chases : s
B chases : s
why? in those two polymorphism was never used it's a "regular objects"
a.chase('s');
b.chase('s');
aptr = &b; <-we gave aptr the address of a b object
since chase is virtual now polymorphism kicks in
aptr->chase('s');
same goes with references:
aptr = &b;
aptr->chase('s');
but what you did was actually this:
a = b; here b copies it's "A" part into a but since a can't hold the "B" part
it doesn't hold it as far as it concern it thinks of b as an A object
a.chase('s'); so that will yield the A chase and not the B chase
so tips: polymorphism can be used with: pointers(smart pointers or raw pointers like i used in my example) or reference.
if you wanna use polymorphic powers it will do iff you used pointers/references
another tip is use override to notice the compiler that you're overriding a "parent" function it will help you when you have bad parameters and etc( will produce proper compiler error and etc.
and one of the most vital things is always make your destructor in the base class virtual to make sure no zombies will appear
Your Board class contains an array of Ghost objects, not Chase objects. So G[0].chase(bD); will always call Ghost::chase(), never Chase::chase(). Just because you define an override in Chase does not mean it is used automatically everywhere a Ghost is used. Polymorphism only works when you have a pointer/reference of a base class type pointing at an object of a derived type. Your code does not have that. To fix that, make your array hold Ghost* pointers that point at Chase objects. For example:
class Board
{
private:
Ghosts* G[4];
public:
Board()
{
for (int i = 0; i < 4; i++)
G[i] = new Chase;
}
~Board()
{
for (int i = 0; i < 4; i++)
delete G[i];
}
void Chase(char bD)
{
G[0]->chase(bD);
}
};
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 7 years ago.
Improve this question
In a member function of Class Championship, I try to create dynamic objects and call the member function of Class Game, but I got the error message as error: expected primary-expression before '[' token. How to correct it?
class Championship
{
public:
Championship(string,int);
void CreateGame();
void display();
private:
int gamenum;
};
class Game
{
public:
friend class Championship;
void Getteam();
};
void Championship::CreateGame()
{
Game *game = new Game[gamenum];
for (int i = 0; i < gamenum; i++)
Game[i].Getteam();
}
The exact problem you are facing in your code is in this small bit
Game *game = new Game[gamenum];
for (int i = 0; i < gamenum; i++)
Game[i].Getteam();
The main issue here is that you have declare an array of type Game and call it game but then you try to access using Game which is the type, so simply swapping that back to game would fix that issue.
However, there is no need for using raw pointers in this way. std::vector is superior in so many ways here. It allows you to dynamically add more and more objects into the container in a safe way. I was about to show how std::vector could be used in your Championship::CreateGame() function... but I can't really work out what it is trying to do...
I also don't see why you have the friend line in your game class... that is used to give another class 'full' access to your class, ie the Championship class is given access to private members of Game.
Edit: While this answer doesn't directly solve the problem, it does provide a useful alternative syntax for allocating arrays of User-Defined Objects.
This can probably be solved not-so-elegantly using the classic C-style double-pointer array (i.e. argv from int main(int argc, char** argv). Such code would first allocate the space for the array, and then allocate the space for each individual object using a loop with an index.
#include <iostream>
class Foo
{
public:
//Constructor to ensure each object is unique with an int + loop
Foo(int k)
: i(k)
{}
int i;
int operator() () {return i;}
};
int main ()
{
//Arbitrary number for allocation; get this somehow
int i = 5;
//Although it can be unsafe, allocate an array of pointers with a pointer to pointer
Foo** array = new Foo*[i];
for (int j = 0; j < i; ++j)
{
array[j] = new Foo(j);
//Here, I use operator() to test that each object is unique.
std::cout << (*array[j])() << std::endl;
}
//Using Coliru, the program will work and print out this
std::cout << "this worked!\n";
return 0;
}
Coliru: http://coliru.stacked-crooked.com/a/84f7641e5c4fa2f3