473,396 Members | 1,748 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

vector and shared_ptr to base class

I am trying to make the following:

struct Base
{
char param[FIXED_NUMBER];
};

class Derived1 : public Base
{
public:
void setParam(char c)
{
param[1] = c;
}
};

class Derived2 : public Base
{
public:
void setParam(char c)
{
param[2] = c;
}
};

shared_ptr<Derived1d1(new Derived1);
d1->setParam(0x10);

shared_ptr<Derived2d2(new Derived2);
d2->setParam(0x20);

//What the best way of doing this?
vector<shared_ptr<Base v;
v.push_back(d1);
v.push_back(d2);
....
//Somewhere for example
shared_ptr<Baseb = *iter;
reverse_bits(b.param);

Obviously v.push_back(d1) is not going to work because there will be
"no matching function for call". But what the best way of doing this?

Oct 3 '06 #1
5 4963
Dimitry wrote:
I am trying to make the following:

struct Base
{
char param[FIXED_NUMBER];
};

class Derived1 : public Base
{
public:
void setParam(char c)
{
param[1] = c;
}
};

class Derived2 : public Base
{
public:
void setParam(char c)
{
param[2] = c;
}
};

shared_ptr<Derived1d1(new Derived1);
d1->setParam(0x10);

shared_ptr<Derived2d2(new Derived2);
d2->setParam(0x20);

//What the best way of doing this?
vector<shared_ptr<Base v;
v.push_back(d1);
v.push_back(d2);
...
//Somewhere for example
shared_ptr<Baseb = *iter;
reverse_bits(b.param);

Obviously v.push_back(d1) is not going to work because there will be
"no matching function for call". But what the best way of doing this?
Not going to work if your 'Base' is non-polymorphic class. If you do

struct Base {
char param[WHATEVER];
virtual ~Base() {}
virtual void setParam(char) = 0;
};

*Then* you could try

vector<shared_ptr<Base v;
v.push_back(new Derived1);
v.push_base(new Derived2);
v[0].setParam(0x10);
v[1].setParam(0x20);
...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Oct 3 '06 #2
If for example Derived1 has setParam1 function, Derived2 - setParam2
etc. and I have a lot of these derived and each derived has own
customized 'set'-functions that Base class has no idea of.
How can I make it properly?
For example:
struct D1 : Base
{
void setParam1(){..}
void setParam2(){..}
void setParam3(){..}
};

struct D2 : Base
{
void setParam4(){..}
};

struct D3 : Base
{
void setParam5(){..}
void setParam6(){..}
};
Victor Bazarov wrote:
Not going to work if your 'Base' is non-polymorphic class. If you do

struct Base {
char param[WHATEVER];
virtual ~Base() {}
virtual void setParam(char) = 0;
};

*Then* you could try

vector<shared_ptr<Base v;
v.push_back(new Derived1);
v.push_base(new Derived2);
v[0].setParam(0x10);
v[1].setParam(0x20);
Oct 3 '06 #3
[rearranged]
Victor Bazarov wrote:
Not going to work if your 'Base' is non-polymorphic class. If you do

struct Base {
char param[WHATEVER];
virtual ~Base() {}
virtual void setParam(char) = 0;
};

*Then* you could try

vector<shared_ptr<Base v;
v.push_back(new Derived1);
v.push_base(new Derived2);
v[0].setParam(0x10);
v[1].setParam(0x20);
hmm, v[0]->setParam(...);

Dimitry wrote:
If for example Derived1 has setParam1 function, Derived2 - setParam2
etc. and I have a lot of these derived and each derived has own
customized 'set'-functions that Base class has no idea of.
How can I make it properly?
For example:
struct D1 : Base
{
void setParam1(){..}
void setParam2(){..}
void setParam3(){..}
};

struct D2 : Base
{
void setParam4(){..}
};

struct D3 : Base
{
void setParam5(){..}
void setParam6(){..}
};

Thats exactly what Victor is trying to explain.

The base class doesn't need to know anything. What D2 does is also
inconsequential to D3, etc. Even the container that will store a
mixture of these doesn't care about the derived class's specifics or
internals.
The goal here is to provide a base class where the creator of the class
(you) can impose a rule that says: "You must provide the implementation
for this pure virtual member function if you choose to derive from this
base class - my system requires it". This way the derivatives can
safely use a polymorphicly distributed member function to fullfill its
particular needs and the container will always have that virtual member
function available regardless of the actual type of the element
involved. Sounds complicated but its a simple concept.

#include <iostream>
#include <vector>

struct Base // pure abstract
{
virtual ~Base() { std::cout << "~Base()\n"; }
virtual void setParam() = 0; // pure virtual member function
};

class D1 : public Base
{
void setParam1() { std::cout << "setParam1()\n"; } // private
void setParam2() { std::cout << "setParam2()\n"; }
public:
~D1() { std::cout << "~D1()\n"; }
void setParam() // required by Base
{
std::cout << "setParam()\n";
setParam1();
setParam2();
}
};

int main()
{
// Base base; // illegal - its abstract
vector< shared_ptr< Base v;
v.push_back( new D1 ); // etc...
v[0]->setParam(); // does the D1 boogie, whatever that might be
}

/*
setParam() // system-wide
setParam1() // internal
setParam2() // internal
~D1()
~Base() // correctly invoked by derived d~tor
*/

Note how the container doesn't care about what D1 actually does. Thats
the element-type's responsability alone. Why is that important? Cause
then the system is easy to expand and hard to break. You, the creator,
have imposed a small rule in order to use the code. The client
programmer can expand the system knowing that the its safely
extendeable. And the client can do this with the assurance that he can
add new derivatives 2, 5 or 10 years from now whithout having to
change/modify a single line of the original code.

As a side note, in this case, i'ld probably be using the ctor's init
lists to set members instead. 'Course, i don't know what the
requirements are...

class D2
{
const char a;
const char b;
public:
D2() : a('a'), b('b') { }
D2(char a_, char b_) : a(a_), b(b_) { }
D2() : a( setParam1() ), b( setParam2() ) {} // no problem
const char setParam1() const { return 'a'; }
const char setParam2() const { return 'b'; }
};

but thats an entirely different issue.

Oct 3 '06 #4
Thanks guys,

What I actually meant is setParamN shall be public.
Let's put this different way:

void makeMagicQuick(string s)
{
//make magic with Base::param
}

void makeMagicSlow(int i)
{
//make magic with Base::param
}

void makeMagicAsUsual(vector<..>& v)
{
//make magic with Base::param
}
....
And number of such makeMagicN is a lot and each does own trick with
Base::param.
This is why we need derived classes in a first place to make the
Base::param more friendly.
Each makeMagic is a meaningful name and makeMagicQuick and
makeMagicSlow have nothing in common apart from that they use
Base::param.

Oct 3 '06 #5

Dimitry wrote:
Thanks guys,

What I actually meant is setParamN shall be public.
Whether setParamN is public, protected, private or even non-existant is
irrelevent. setParamN is not part of the Base's interface. And your
goal is to store Base-type elements. So you could implement RTTI and do
it the ugly way or you can simply use the concept already explained to
you.
Let's put this different way:

void makeMagicQuick(string s)
{
//make magic with Base::param
}
That makes no sense. makeMagicQuick is not a type's member function.
Functions do not have Bases and neither are they objects.
>
void makeMagicSlow(int i)
{
//make magic with Base::param
}

void makeMagicAsUsual(vector<..>& v)
{
//make magic with Base::param
}
...
And number of such makeMagicN is a lot and each does own trick with
Base::param.
This is why we need derived classes in a first place to make the
Base::param more friendly.
Base::param serves no one. The derived entities are being classified
using the Base's type. Each derived entity enjoys the priveledge of
having a Base counterpart. And it is a priveledge because without it,
you can't store the derived instances in one Base container.
Each makeMagic is a meaningful name and makeMagicQuick and
makeMagicSlow have nothing in common apart from that they use
Base::param.
What? makeMagic is not an object and therefore can't have a Base. You
are making no sense at all.

Oct 3 '06 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

20
by: Agent Mulder | last post by:
Hi group, I have a class called container with a vector of pointers to some base class as member. Can someone help me find the right destructor for this class? Thanks, Martijn Mulder
4
by: The Directive | last post by:
I can't understand why in this folling example the message "Base.Draw()" is printed. Shouldn't "Derive.Draw" be printed because of polymorphism? How can I rewrite this example using a vector to...
5
by: ma740988 | last post by:
Hopefully I'm not asking too much here, nontheless consider the test source: #include <vector> #include <utility> using std::vector; using std::pair; #define INVALID_ID -1
32
by: zl2k | last post by:
hi, c++ user Suppose I constructed a large array and put it in the std::vector in a function and now I want to return it back to where the function is called. I can do like this: ...
6
by: lokchan | last post by:
i want to create a vector of pointer s.t. it can handle new and delete but also have std::vector interface can i implement by partial specialization and inherence like follow ? #include...
3
by: nw | last post by:
Hi, I have three classes, a template pure virtual base class, a template derived class and a third which I would like to use to store copies of the derived class. The code looks like this: ...
6
by: Jia | last post by:
Hi all, I have a class foo which has a static vector of pointers of type base class, and a static function to set this vector. #include <iostream> #include <vector> using namespace std;...
13
by: jubelbrus | last post by:
Hi I'm trying to do the following. #include <vector> #include <boost/thread/mutex.hpp> #include <boost/shared_ptr.hpp> #include <boost/tuple/tuple.hpp> class {
3
by: Ramon F Herrera | last post by:
Newbie alert: I come from C programming, so I still have that frame of mind, but I am trying to "Think in C++". In C this problem would be solved using unions. Hello: Please consider the...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.