I am currently creating a class that has to be derived from std:: vector. I realize its probably bad to do this but I'm required to. Now my question is how do you access the created vector in the member functions to basically make the class access itself like a regular vector of integers? For example I am looking for the equivalent of myVector.at(0) to return the first term in the vector. Also, the size of the vector should always be 6. Here is the code I have so far:
class aHistogram : public vector<int>
{
public:
aHistogram(); //default constructor for histogram class
void update(int face); //Function to update histogram
void display(int maxLengthOfLine); //Displays histogram to the scale of maxLengthOfLine using x's
void clear();//Function to clear histogram bin counts
int count(int face) const; // Function to return number of times a face has appeared
private:
int numx, m, j; //Variables used in functions
};
#endif
The function that requires the class to access itself is below, I know there is no vector called "myVector" but what I'm lost about is the equivalent syntax to be able to perform the operation.
void aHistogram::clear()
{
//Clears bin counts to 0
myVector.at(0) = 0;
myVector.at(1) = 0;
myVector.at(2) = 0;
myVector.at(3) = 0;
myVector.at(4) = 0;
myVector.at(5) = 0;
}
If the function in question isn't overridden in the derived class, you
can just call it:
void HistoGram::clear()
{
at( 0 ) = 0;
// ...
}
This is also true for operators, but you'll have to use (*this) as the
left hand operator:
void HistoGram::clear()
{
(*this)[0] = 0;
// ...
}
If the function or operator is overridden, you'll either have to
qualify the function name,
void HistoGram::clear()
{
std::vector<int>::at( 0 ) = 0;
// ...
}
or cast the this pointer to the base class type:
void HistoGram::clear()
{
(*static_cast<std::vector<int>*>( this ))[0] = 0;
// ...
}
But are you sure that you want public inheritance here? You state that
the size of the vector should always be 6. There's no way you can
guarantee that using public inheritance; at the least, you need private
inheritance, and then using declarations for the operations that you
want to support. (I've a couple of cases where I've needed restricted
std::vector like this, which I've implemented using private
inheritance. And sometimes forwarding functions, when for example
I've wanted to expose only the const version of the function.)
Also: there are very, very few cases where std::vector<>::at is
appropriate. Are you sure you don't want [], with the bounds checking
you get in most modern implementations.
Instead of deriving from std::vector, in this case contain one (as a data member).
The problem with deriving is that it's then possible to treat a Histogram instance as just a std::vector, doing things that invalidate assumptions about the values of added data members.
In more technical jargon, with class derivation you have no guaranteed class invariant above the one provided by std::vector.
As a general rule of thumb, think of data member before class inheritance.
Sometimes inheritance is the thing, even inheritance from standard library container classes (e.g., std::stack is designed for inheritance), but not in this case.
About this: the size of the vector should always be 6.
You probably want to forbid some functionality to the user of the class. For example
vector::push_back
vector::pop_back
vector::insert
are functionalities that can change the size of the vector.
You can achive this by making such functions private members in the child class:
class aHistogram : public vector<int>
{
public:
aHistogram(){};
private:
vector<int>::push_back;
vector<int>::pop_back;
vector<int>::insert;
int numx, m, j;
};
Related
Given a C++ class with assorted member data values and a static int counter, I'd like to have a clear() function that can walk all the elements of an array of these class objects clearing their data members.
So, for example, a class that looks like this and holds a chip's version information (yes, I know I probably need more setters and getters):
class __STA_version_t
{
public:
__STA_version_t() { count++; };
~__STA_version_t() {};
void setVerString( char* x ) { strncpy( verString, x, sizeof(verString)); verString[sizeof(verString)-1] = 0
void clearVerString() { memset( verString, 0x0, sizeof(verString) ); }
char* getVerString() { return verString; }
bool hasVersion() { return verString[0]; }
void clear()
{
for ( int i = 0; i < count; i++ )
{
// what goes here?
}
}
private:
static int count; // how many of these objects exist, need to know for clear().
char verString[20]; // station version as a string
UINT8 major_ver; // major version identifier (3 bits)
UINT8 minor_ver; // minor version identifier (6 bits)
UINT8 revision; // revision identifier (4 bits)
UINT8 chip_ident; // target chip identifier (3 bits)
};
Elsewhere initialize count thusly:
__STA_version_t::count = 0;
Now, create an array of there objects:
__STA_version_t versions[10];
First, just checking, count should equal 10 after this instantiation, right?
In the clear() function, I'd like to say something like:
this[i]->clearVerString();
this[j]->revision = 0;
// etc.
to clear each data member of each element of the array.
Can this be made to work? How?
The issue is that the class can't see outside its boundaries and the container is outside of the class' boundary.
You should use a standard container. Make the clear method clear data members in the class.
The standard containers have methods for determining the number of items.
See std::vector, std::list, std::map, etc.
What you are trying to do is not very "object oriented" IMO. I would argue that the class clear() member function you are trying to implement here should only clear the data of the instantiated object on which it is invoked. What you are trying to do is clear the data in all instantiations of your class, via calling clear() on any/one of them only?
A better approach here would be to store your objects in a std::vector<__STA_version_t>, and then write a static function on your class that either takes the vector as a parameter (ideally), or can access it globally somehow, called maybe clearAll(). Have that function iterate through the vector and call clear() on each object in the vector. The clear() function would then simply call clearVerString() etc on itself - eg:
this->clearVerString();
this->revision = 0; and so on (noting that you don't actually need to use the this pointer if you don't want to).
I think I have a design issue here and I would really appreciate your help.
I have a class Base representing a basic algorithm.
class BaseAlgo: public Algo<double>
{
public:
/// data structures
// ...
//
struct Item {
double profit;
double weight;
double xjSolution;
};
typedef std::pair<double, std::vector<Item>::iterator> ScaledItem;
protected:
std::vector<Item> & items_;
boost::ptr_vector<ScaledItem> largeItems_;
}
The BaseAlgo has some functions, some of them virtual, others not.
As a derived class I have
class DerivedAlgo: public BaseAlgo
{
public:
/// enhanced data structures
// ...
//
struct DerivedScaledItem : ScaledItem {
int additional;
};
}
In my virtual functions which I overload in DerivedAlgo, I need access to the additional parameter of DerivedScaledItem which is not quite the original intent of polymorphism. Is it somehow possible or do you propose a different design approach? I am open to anything at the moment as I am completely stuck.
Right now, the largeItems_ member ptr_vector in BaseAlgo holds ScaledItems (internally as pointers). I thought, I could use this somehow like this:
// in DerivedAlgo
void someMethod(std::vector<Item>::iterator someiterator){
DerivedScaledItem doubledItem = {};
doubledItem.first = 4.5;
doubledItem.second = someiterator;
doubledItem.additional= 2;
largeItems_.push_back(new UnboundedScaledItem(doubledItem));
boost::ptr_vector<DerivedScaledItem>::iterator it = largeItems_.begin();
std::cout << "added large item " << *it << std::endl;
}
When I cout the just added object, additional is set to 2. But after that, calling the getter for largeItems_, the additional field will be set back to 0, only the two fields which are known in ScaledItem are then set.
// in BaseAlgo
const boost::ptr_vector<ScaledItem>& getLargeItems() const
{
return largeItems_;
}
// from my test.cpp
DerivedAlgo obj;
// ... define someiterator
obj.someMethod(someiterator);
boost::ptr_vector<BaseAlgo::ScaledItem> largeItems = knapsack.getLargeItems();
boost::ptr_vector<DerivedAlgo::DerivedScaledItem>::iterator it = largeItems.begin();
std::cout << "read large item " << *it << std::endl;
I guess you didn't tell boost how to clone your ptr_vector-s elements, like described here:
http://www.boost.org/doc/libs/1_54_0/libs/ptr_container/doc/tutorial.html#cloneability
So in this line, where you create a copy of the vector (you could avoid this by declaring largeItems as a reference), they get copied via the constructor of ScaledItem, which looses your additional member.
boost::ptr_vector<BaseAlgo::ScaledItem> largeItems = knapsack.getLargeItems();
Regarding your question about another design:
You could pass the type of the vectors elements as a template parameter to the base class.
You could move the vector into the derived class, and provide only (virtual, abstract) functions to access single elements in the base class. If the base class shall also be able to create elements, you may need some kind of factory method. Because you don't want the base kind of elements in the vector.
I'm currently pondering how should I go about making a 2D vector array for a sort of a game board.
The board should be vectors because the size can vary, and each "square" should contain information about what objects are in that square.
The problem is that there can be overlapping objects, and the objects may not be the same type or class.
This is what I'm currently considering: (pseudo code)
struct Square {
vector<enum type>;
vector<pointers to objects>;
};
vector< vector <Square> >;
And the pointer's would point to different vector arrays each holding specific objects.
I'm unsure how to make such functionality or if this is even possible, and I'm seriously thinking this might be more complicated then it needs to be..
Some objects must be classes, but I could make all the types of objects in the game board classes that inherit from one master class.. But in the end the objects are completely different so I'm not sure if that makes much of a difference.
Am I just being blind and missing a easier way to do what I'm trying to do: 2D array holding different types of elements that can also overlap in the array?
I'd really appreciate any help, snippets or insight.
Notes:
Board size won't chance after creation.
Objects must be able to move around in the board.
Here's what I would suggest.
#include <boost/shared_ptr.hpp>
class GameObject {
public:
virtual ~GameObject() {}
enum Type {
FOO,
BAR
};
virtual Type type() const = 0;
virtual std::string name() const = 0;
virtual void damaged() {}
};
class FooObject : public GameObject {
public:
Type type() const { return FOO; }
std::string name() const { return "Foo object"; }
void damaged() {
std::cout << "Foo was damaged!" << std::endl;
}
};
class BarObject : public GameObject {
public:
Type type() const { return BAR; }
std::string name() const { return "Bar object"; }
// Bar object doesn't respond to damage: no need to override damaged()
};
class Square {
std::vector<boost::shared_ptr<GameObject> > objects;
};
class Board {
// Details of the implementation here not important, but there
// should be a class to hide them.
Square* squares;
int width, height;
Board(int width, int height) :
squares ( new Square[ width * height ] ),
width ( width ),
height ( height )
{
}
~Board() {
delete [] squares;
}
Square& square(int x, int y) {
if( x < 0 || x >= width || y < 0 || y >= height ) {
throw std::logic_error( "accessed square out of bounds" );
}
return squares[ x + width * y ];
}
};
Summary:
Have a single base class for all sorts of objects that can be placed on a game board.
A class of this type must have a virtual destructor, even if it's trivial. This is because you will be deleting things through GameObject pointers.
If it's necessary to distinguish the game objects, use a virtual method returning a 'type' value.
As far as it's not necessary to use it, don't use that type value, but use other virtual methods that do meaningful things instead. Using the type value (and then generally casting to the subtype) should be considered a last resort. For instance (inventing details about your game freely):
Every object has a name that shows when you put the cursor over it. This is returned in name().
Events in the game may cause 'damage' an object. This only applies to some sorts of objects, so the default action on damaged() is to do nothing. Foo-objects, which respond to damage, override this with an actual action.
However you implement the board, hide your exact implementation away in a class. (Don't take my code as an indication that you shouldn't use vector<> for this, that's definitely fine. I have a slight personal preference against vector< vector<> > here, but that's not too bad either.)
Use shared pointers for the game objects.
Boost has a great and widely used implementation.
If you can't use shared pointers, control the lifetime of your game objects outside the Square class (say, in a master list of all game objects in the Board class), and then use raw pointers in the Square class.
If you do use shared pointers, and it's the first time you do, briefly read up on them first. They're not magic, you need to beware of certain things such as circular references.
Depending on your needs, you may want to have a "backlink" in GameObject to the squares, or the coordinates of the squares, that contain pointers to that GameObject. This will allow you to easily remove objects from the board and move them around.
So this is the situation.
I have a class
Class L_FullQuote
{
private:
vector<int> time;
..
}
and
Class B
{
L_FullQuote *Symbols[100];
void handle message()
}
Inside handle msg
i have this statement
Symbols[i]->time.push_back(2);
the code builds fine..but when i use the generated dll. the application just crashes..sometimes it takes me to a nxt poiner error in vector..but mostly the whole application just crashes.
It works fine without that line.
Please help
Thanks
You're already using vector, so why not take it one step further? Using std::vector will allow you to focus on writing your functionality, rather than worrying about memory management.
This example differs slightly from what you originally posted. Your original question class B has an array of 100 pointers that each must be initialized. In the example below, we create a std::vector of L_FullQuote objects that is initially sized to 100 objects in the constructor.
class L_FullQuote
{
public:
vector<int> time;
};
class B
{
public:
// Initialize Symbols with 100 L_FullQuote objects
B() : Symbols(100)
{
}
std::vector<L_FullQuote> Symbols;
void handle_message()
{
Symbols[i].time.push_back(2);
// other stuff...
}
};
L_FullQuote *Symbols[100];
Here you declare an array of pointer to L_FullQuote, but you never initialize any of the pointers, so when you call:
Symbols[i]->...
You are dereferencing an invalid pointer. Also note that you have declared time as private (though your code wouldn't even compile this way, s B as a friend of A I assume?)
Simply declaring an array of pointers does not initialize each element to point to a valid object. You need to initialize each one, something like:
for(int i = 0; i < 100; ++i) {
Symbols[i] = new L_FullQuote();
}
Only then do you have an array full of valid pointers. Don't forget to deallocate them though!
time is private member of class L_FullQuote, from class B you don't have access to that field
I am implementing a simple board game (Breakthrough) using OpenGL (plus GLUT and GLUI).
I'm thinking of implementing a Board class, which will have a vector<vector<Cell> > as one of its attributes. Cell represents a space in the game board. It can contain a GameObject. GameObject will be a pure abstract class. It mandates that its derivative classes implement render(), for example. Possible derivative classes will be:
Blank, representing an empty space
Pawn, representing a pawn (the only possible pieces in Breakthrough)
The board will be rendered by first rendering the board, then iterating through each Cell, getting its contents and calling render() for each of them.
The only possible way I can think of to achieving this is making the GameObject in Cell a pointer (board[y][x].getContents()->render(), where getContents() returns the GameObject*)
Is this the best way to do this? Is this an appropriate usage of pointers?
Let me promote my comment into an answer. This doesn't mean that it's in any sense complete, only that this allows me to spell out some code examples. My original comment:
That's OK, though you probably would do better with a std::unique_ptr<GameObject> or a std::shared_ptr<GameObject> so you don't get lost amids the manual lifetime management issues. Finally, how about a flat 1-D array accessible in strides?
Here's how I might go about this:
#include <vector>
#include <memory>
struct GameObject { virtual void render() const = 0; virtual ~GameObject() { } };
class Cell
{
std::unique_ptr<GameObject> m_go;
public:
void render() const { m_go->render(); }
Cell() : m_go(new BlankCell) { }
// more functions to reassign the cell value etc.
};
class Board
{
std::vector<Cell> m_board;
std::size_t m_length;
public:
Board(std::size_t length) : m_board(length * length), m_length(length) { }
Cell & cell(std::size_t i, std::size_t j) { return m_board(j + i * m_length); }
Cell const & cell(std::size_t i, std::size_t j) const { return const_cast<Board*>(this)->cell(i, j); }
// more...
}
Yes.
Also, maybe you should use another container for your cells (some kind of matrices or so)