|
yogeshs wrote: boost::iostream namespace
...and that's even with a trailing 's' in boost::iostreams?
|
|
|
|
|
Hello Nikalas
I am using iostreams.
and I am getting this error.
error C2039: 'zlib' : is not a member of 'boost::iostreams'
error C2871: 'zlib' : a namespace with this name does not exist
Is it possible that full package of boost library is not there?
Thanks For Ur Reply
Regards
Yogesh
|
|
|
|
|
yogeshs wrote: Is it possible that full package of boost library is not there?
That can of course be the case, but then you would get an error with
#include <boost/iostreams/filter/zlib.hpp>
Have you verified that you have that file? And if so have a look in it, and look at what namespace is used.
I revisited this file[^] and found that the namespace should be boost::iostreams . My bad.
But the zlib namespace should still be there, so there is probably something else missing for you.
|
|
|
|
|
Let me use example to describe what I need:
class Top
{
public:
virtual void something()=0;
int iType;
};
class SubA : public Top
{
public:
SubA() {iType=0;}
virtual void something(){}
};
class SubB : public Top
{
public:
SubB() {iType=1;}
virtual void something(){}
};
CArray<Top*,Top*> aryTop;
aryTop contains a set of pointers to SubA and/or SubB.
I need to cast Top* in the array to correct sub class, that is, an auto_cast() may return SubA* or SubB* by value of iType. auto_cast() may be macro, function or any idea.
i.e.
Top*p=aryTop.GetAt(0);
SubA*pa=auto_cast(p);
SubB*pb=auto_cast(p);
Do you have idea to do so?
|
|
|
|
|
The dynamic_cast operator works just like you want, and it doesn't need the iType member, because it rely on the RTTI:
Top* p = aryTop.GetAt(0);
SubA* pa = dynamic_cast<SubA *>(p); SubB* pb = dynamic_cast<SubB *>(p);
|
|
|
|
|
We call it dynamic_cast[^] operator.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
It's easy to do, as others have said you can just use dynamic_cast, but should you really do it? Generally no. As soon as you start downcasting (with a few exceptions - pardon the pun) it's a sign that you've missed a virtual function somewhere. And as soon as you start missing virtual functions you're coupling your code more tightly than it needs to be - which usually ends up with ages compile times and people becoming scared of anything in an h file.
So if you've got a situation like...
I *p = <something set yonks ago>;
if( A *a = dynamic_cast<A *>( p ) )
{
a->do_a_specific_thing();
}
else if( B *b = dynamic_cast<B *>( p ) )
{
b->do_b_specific_thing();
}
think of modifying I instead so you end up with:
I *p = <something set yonks ago>;
p->do_specific_thing();
You make it easier to maintain (if you're maintaining the code you don't have to know about A and B) and extend (you can add another subclass without changing the client code). So if you're using dynamic_cast<> consider if you really need the client code to know about the concrete type of the objects it's operating on.
(And the same goes for type fields, they're even more useless and redundant than dynamic_cast).
Cheers,
Ash
Cheers,
Ash
|
|
|
|
|
...and if do_a_specific_thing and do_b_specific_thing have different signatures ?
|
|
|
|
|
If they do then that shows that your design is a bit bent and that perhaps A and B aren't related types at all and shouldn't be stored in the same collection. It's heading towards storing void pointers.
However if you have to do this (because you're using someone else's classes) that you can't modify then abstracting the operation and the original classes into independent hierarchies is the most general way to go. If you do that then you can still keep the clients from needing to know the exact classes and operations they're using. The only types that need to know the concrete types are the operation types but you end up paying the same sort of efficiency penalty you pay using dynamic_cast to do your dispatch.
Cheers,
Ash
|
|
|
|
|
Aescleal wrote: If they do then that shows that your design is a bit bent and that perhaps A and B aren't related types at all and shouldn't be stored in the same collection.
actually, it just shows that A and B use different input for some things. even the best design still has to deal with real life.
|
|
|
|
|
I'd have thought it would have shown that inheritance is not the correct thing to model "real life" in this case. If during processing of a collection you can't handle them in a uniform way then it's really dodgy gathering them up in the same place. If they haven't got a consistent interface to them then you're just asking for big headaches later.
In the "real world" (which is the place presumably programs deal with "real life") as soon as you start tacking on little lumps of interface on an ad-hoc basis you're opening the poor bugger that comes after you with a nightmare when he or she has to add a new concrete type that implements an interface. Not only have they got to implement the interface but they have to grub around in every client of the interface looking for the place where some form of dynamic_cast is happening and check there's no conversion there. If that's "real life" I'll stick with my ivory tower.
So if you really need to have something that processes two related classes in a different way, why not maintain a collection for each type? Something like:
std::vector<A> the_As;
std::vector<B> the_Bs;
You can then replace all the looping and dynamic_casting with:
std::for_each( the_As.begin(), the_As.end(), std::mem_fun( &A::do_something_A_related ) );
std::for_each( the_Bs.begin(), the_Bs.end(), std::mem_fun( &B::do_something_B_related ) );
replacing the final arguments with something that makes sense in either context (functors, bound functions taking different arguments)? Then it doesn't matter if A and B are related or not - you can process them independently or as a group. Admittedly you're still handling concrete types rather than interfaces but at least you're separating out the functionality rather than munging them together in one great melange. You can even have a collection for the interface pointers:
std::vector<I *> the_Is;
and not have to worry about deleting the objects pointed to as the other two collections handle that.
Another alternative is to say "A and B aren't related but share some characteristics I'd like to process similarly." You then implement A and B as concrete types without any inheritance relationship and THEN implement two bridges or adapters that implement I in terms of A and B.
Both these (rather stream of consciousnes) examples show that there's more ways to skin the feline than just saying "Oh sod it, dynamic_cast the difference." As I said before dynamic_casting or type switching is a sign that there's something cleaner inside waiting to get out.
Cheers,
Ash
|
|
|
|
|
Aescleal wrote: If during processing of a collection you can't handle them in a uniform way then it's really dodgy gathering them up in the same place.
you're thinking design-time. i'm thinking product-lifecycle-time.
if the design of v1.0 didn't anticipate everything v7.8 would be asked to do, you might end up with a collection of things which have deviated somewhat from the initial design. you might end up in a situation where objects of type A need a little extra attention because they've grown out of their training pants.
it happens.
|
|
|
|
|
I hate to break this to you but there's no specific "design time" in a product lifecycle. Everytime you modify the code you're making a design decision. What you're alluding to is that whatever collection of interfaces version 1 has has to be immutable for every version thereafer.
If objects of type A need a bit more attention change the interface it implements - it'll be a lot less pain in the long run. As soon as you move (or add) concrete class specific code out of the concrete class you make problems for yourself.
|
|
|
|
|
Aescleal wrote: I hate to break this to you but there's no specific "design time" in a product lifecycle
I would kindly disagree, design just comes in iterations. Non-stop redesign would be harmful for productivity IMHO (more details). I agree that coding is a design activity rather than a engineering activity (which requires small design decisions at every stepl), in practice redesign of classes/interfaces/flow should be done when needed.
/M
|
|
|
|
|
Aescleal wrote: I hate to break this to you but there's no specific "design time" in a product lifecycle.
|
|
|
|
|
I've got some 3rd party static libs in C++ using STL.
To use them in C projects without STL I wrapped them in some C++ lib providing extern "C" declaration which hides all STL and C++ stuff from the resulted header providing just void* pointers to data to be processed.
I linked them explicitly to that wrapper lib as in any C project all is needed just to link to that wrapper lib.
In VS2008 all C projects compiled normally.
After I converted those to VS2010 they started to ask those C++ libs with STL which are already present in the wrapper lib.
What is the problem VS2010 fails to see them already lnked to the wrapper?
Чесноков
|
|
|
|
|
Are you sure that MyCplusplusWithSTL.lib is in a directory that the linker is searching?
It's time for a new signature.
|
|
|
|
|
It does not need to.
There is 'MyWrapper.lib' which already linked explicitly with 'MyCplusplusWithSTL.lib' (the latter is added to additional dependencies in MyWrapper lib project)
Exe is a C project which needs only 'MyWrapper.lib' to be compiled. It worked in that mode with VS 2008.
However with VS2010 during C project compilation it asks for 'MyCplusplusWithSTL.lib'.
There is no need to include any lib explicitly to other lib project. In that case during exe compilation all libs should be added to additional dependencies.
In my case exe project is a C one without STL. That is why I used wrapper to remove 'MyCplusplusWithSTL.lib' dependency to be added to C project.
Чесноков
|
|
|
|
|
I know that quite a few things changed with VS2010 in terms of the build process. You need to check through all your project settings to make sure that no reference was transferred incorrectly.
It's time for a new signature.
|
|
|
|
|
C exe project links to only 'MyWrapper.lib' declared in additional dependencies. The same as in VS2008.
After I compile that exe project it asks for 'MyCplusplusWithSTL.lib' which was already linked before explicitly in 'MyWrapper.lib'
Чесноков
|
|
|
|
|
Maybe you should include MyCplusplusWithSTL.lib in your project and see what happens. I cannot guess why this is happening without seeing your entire project(s).
It's time for a new signature.
|
|
|
|
|
i am trying to use SHGetFolderPath and i get " error C3861: 'SHGetFolderPath': identifier not found" , i have included the #include "Shlobj.h", it seems that i need to "have shell32.dll" how can i do this? or any other ideas about how to solve this problem?
|
|
|
|
|
|
you can also you following code:
#pragma comment(lib,_T("Shell32.Lib"))
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
That looks like a compiler error rather than a link error so it's more likely to be something up with the include file. Have a check that:
- you've included it and there's nothing around it that might have stopped it being included (i.e. only including it in one path of a preprocessor controlled melange of death)
- that you haven't used a preprocessor directive to eliminate the function declaration - i.e. have you defined WIN32, __WINNT_<whatever> to the correct level to have the function declared?
Cheers,
Ash
|
|
|
|