- new Class(*this) - 6 Updates
- new Class(*this) - 7 Updates
- Sample code for 'Effective Modern C++' - 1 Update
- on main - 4 Updates
- the smaller prog C++ - 6 Updates
- languages by high-quality books - 1 Update
ram@zedat.fu-berlin.de (Stefan Ram): Apr 09 12:49AM >C++ to be like Java or wherever they came from. We don't need a clone >method, because we already have the means to make a copy...via the copy >constructor: »If you need to copy an object in a class hierarchy, write some kind of clone function« Bjarne Stroustrup |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 09 12:56AM >Often we do not need any virtual functions but sometimes we really >do. »Avoid type switching; prefer polymorphism.« Herb Sutter |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 09 02:13AM I am aware of several high-quality book[ serie]s for C++: The C++ programming language Exceptional C++ Effective C++ C++ coding standards (Sutter) (Accelerated C++) (Modern C++ programming) I am aware of one high-quality book for Java: Effective Java Im an not aware of a high-quality book for C#. For C, we have K&R, but it has not been updated for C11 IIRC. So I don't know a high-quality book for C11. One can find books about Java libraries such as Swing or JavaFX, but sometimes they are just repetitions of the documentation of the classes without enlighting stylistic guidelines. Somehow, especially C++ seems to attract good authors. Or maybe C++ programmers need to learn more than programmers for other languages. |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 09 05:18PM >#include<bitset.h> >int x; >main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} (Below, I use »N« for an end-of-line symbol in the source code.) #include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} #include<iostream>Nint main(){std::cout<<"0101010101010101\n0011001100110011\n0000111100001111\n0000000011111111\n";} |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 09 05:38PM >>int x; >>main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} >(Below, I use »N« for an end-of-line symbol in the source code.) #include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} #include<iostream>Nint main(){std::cout<<"0101010101010101\n0011001100110011\n0000111100001111\n0000000011111111\n";} #include<iostream>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)std::cout<<j/(1<<i)%2;std::cout<<'\n';}} |
ram@zedat.fu-berlin.de (Stefan Ram): Apr 09 05:43PM >#include<iostream.h>N#include<bitset.h>Nint x;main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} >#include<iostream>Nint main(){std::cout<<"0101010101010101\n0011001100110011\n0000111100001111\n0000000011111111\n";} >#include<iostream>Nint main(){for(int i=0;i<4;++i){for(int j=0;j<16;++j)std::cout<<j/(1<<i)%2;std::cout<<'\n';}} At my site, I can also replace »std::cout<<'\n'« by »puts("")« above, but I don't know whether this is portable. |
Christopher Pisz <nospam@notanaddress.com>: Apr 08 06:40PM -0500 On 4/8/2015 6:25 PM, Öö Tiib wrote: SNIP > polymorphic. Sometimes we later need a deep copy made from object that > contains dynamically polymorphic components. Lack of such 'virtual clone' > will cause that deep copy to be a big silly mess. Can you give an example of the problem? I am sure there is a better way then defining a Clone method that returns a raw pointer. If I've got a Fish and I want to make a copy that is a Tuna, I can't and shouldn't be able to, until I know the Fish is a Tuna through dynamic cast and check. If I've got a Tuna and I want a Fish, I can copy construct another Tuna and access everything that is part of the Fish. Maybe I am not getting what you are driving at with the description of "dynamically polymorphic". Google doesn't seem to know about the phrase either, just its individual components, which I am sure we all understand. -- I have chosen to troll filter/ignore all subthreads containing the words: "Rick C. Hodgins", "Flibble", and "Islam" So, I won't be able to see or respond to any such messages --- |
"Öö Tiib" <ootiib@hot.ee>: Apr 08 05:49PM -0700 On Thursday, 9 April 2015 02:41:11 UTC+3, Christopher Pisz wrote: > > contains dynamically polymorphic components. Lack of such 'virtual clone' > > will cause that deep copy to be a big silly mess. > Can you give an example of the problem? Slicing will typically cause damaged invariant of most derived object. struct A { A(int a) : a_var(a) {} int a_var; }; struct B : public A { B(int a, int b) : A(a), b_var(b) {} int b_var; }; B &getB() { static B b(1, 2); return b; } int main() { // Assignment by value to a A a(3); a = getB(); // base class subobject of b is copied to a // that may be is not what we want B b2(3, 4); A &a2 = b2; a2 = getB(); // only base class subobject was assigned so // b2.a_var == 1, b2.b_var == 4! // that is next to never what we want return 0; } > I am sure there is a better way > then defining a Clone method that returns a raw pointer. No. There are covariance of raw pointers but there are no covariance of smart pointers. So returning smart pointer would lose virtual of clone method. > If I've got a Fish and I want to make a copy that is a Tuna, I can't and > shouldn't be able to, until I know the Fish is a Tuna through dynamic > cast and check. With clone you can have pool of different fishes and still make deep copy of it. No typeid checking or dynamic casting is needed. The typeid checking and dynamic casting involves that designer of pool of fishes has to have deep knowledge about all of fish types that can be in it. It is ugly to read and error-prone if new fish class is added. That is silly mess of design. > If I've got a Tuna and I want a Fish, I can copy construct another Tuna > and access everything that is part of the Fish. The whole point of dynamic polymorphism is that you can have a Fish (std::unique_ptr<Fish>) that may be only run-time known if it is Tuna or Shark. It did enter the "gulf" from "sea" and so only that 'unique_ptr' value was passed over. > Maybe I am not getting what you are driving at with the description of > "dynamically polymorphic". Google doesn't seem to know about the phrase > either, just its individual components, which I am sure we all understand. Class is dynamically polymorphic when it contains virtual functions. Often we do not need any virtual functions but sometimes we really do. It is typically case when we will have otherwise repetitive table lookup, if-else and/or switch-case chain over some sort of "kind" or "type" member value in C to differentiate between behavior. C++ has virtual functions to make it bit less of a mess and it also can perform better. In some languages like Objective-C or Javascript all methods are virtual. That is at other edge evil since it makes the things too loose and it also hurts performance a bit when virtual is not needed. |
"Öö Tiib" <ootiib@hot.ee>: Apr 08 06:42PM -0700 On Thursday, 9 April 2015 03:56:47 UTC+3, Stefan Ram wrote: > >do. > »Avoid type switching; prefer polymorphism.« > Herb Sutter Often we do not need neither. Often we know full type of objects (so any virtual is pointless). Sometimes we need even more loose coupling. Like "task" is in "schedule" and it is *not* business of "schedule" to care what "task" does to what, only when to invoke it. Having some Task base class with 'virtual void doIt()' is typically worse than to have 'typedef std::function<void()> Task' on such case. So virtual function can be either unneeded or too intrusive. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Apr 09 11:30AM +0100 On Wed, 8 Apr 2015 17:49:47 -0700 (PDT) Öö Tiib <ootiib@hot.ee> wrote: [snip] > No. There are covariance of raw pointers but there are no > covariance of smart pointers. So returning smart pointer > would lose virtual of clone method. Can you unpack this one for me, with an example of what you have in mind? std::unique_ptr and std::shared_ptr have a templated version of the move constructor and move assignment operator and (for std::shared_ptr) copy constructor and copy assignment operator to allow implicit covariant casts in the same circumstances that pointer casts would be available. Contravariant casting using dynamic_cast is missing for smart pointers (unless you do it by hand), but that is rarely what you want anyway. Chris |
Mr Flibble <flibble@i42.co.uk>: Apr 09 03:48PM +0100 On 09/04/2015 11:30, Chris Vine wrote: > available. > Contravariant casting using dynamic_cast is missing for smart pointers > (unless you do it by hand), but that is rarely what you want anyway. Constructors have no bearing on return type covariance as far as virtual sausages are concerned. /Flibble |
"Öö Tiib" <ootiib@hot.ee>: Apr 09 07:56AM -0700 On Thursday, 9 April 2015 13:30:26 UTC+3, Chris Vine wrote: > > would lose virtual of clone method. > Can you unpack this one for me, with an example of what you have in > mind? #include <memory> struct A { // virtuals virtual A* clone() const { return new A(*this); }; virtual std::unique_ptr<A> smart_clone() const { return std::unique_ptr<A>(new A(*this)); } }; struct B : public A { // overrides B* clone() const override { return new B(*this); }; // OK std::unique_ptr<B> smart_clone() const override { return std::unique_ptr<B>(new B(*this)); } // compile error }; Raw pointers have covariance; smart pointers have no covariance in context of virtual functions. > copy constructor and copy assignment operator to allow implicit > covariant casts in the same circumstances that pointer casts would be > available. It is not enough to affect the problem I described. I have to return 'std::unique_ptr<A>' from 'smart_clone' of B or there are no override. However that means the 'smart_clone' is less convenient than 'clone' in situation where I need deep copy of 'std::unique_ptr<B>' and so expect to have 'std::unique_ptr<B>' as well. > Contravariant casting using dynamic_cast is missing for smart pointers > (unless you do it by hand), but that is rarely what you want anyway. I consider usage of 'dynamic_cast' only on the ultra rare cases when I need cross casting. Otherwise I simply don't use it. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Apr 09 06:06PM +0100 On Thu, 9 Apr 2015 07:56:59 -0700 (PDT) > smart_clone() const override { return > std::unique_ptr<B>(new B(*this)); } // compile error > }; [snip] > convenient than 'clone' in situation where I need deep copy of > 'std::unique_ptr<B>' and so expect to have 'std::unique_ptr<B>' as > well. OK, thanks, I see the point. Chris |
DeMarcus <demarcus_at_hotmail_com@tellus.orb>: Apr 09 06:59PM +0200 > Hello group, > I was one of the reviewers for Scott Meyers his 'Effective Modern C++' book. During the review process, I have created lots of sample code for the material from the book. I am currently revising that sample code and uploading it to my GitHub repository https://github.com/BartVandewoestyne/Effective-Modern-Cpp I have 27 out of the 42 items online already, and hope to add the remaining 15 soon. Feel free to contribute by sending me pull requests! Comments and suggestions are also highly appreciated! > I hope that this online code will help the EMC++ readers to get a hands-on feeling for the principles explained in the book. Feel free to play with this code as much as you like and spread the message! One thing that might be out of scope for the book, but something that I wanted to understand when I read it, was how std::forward /really/ works. In the book and the example code it only brings up the universal reference T&& case. This is fine since I guess std::forward and T&& are used together in 99% of the cases. What I needed to understand was what happens if you have a template that takes T and not T&&. template<typename T> class SomeClass { public: SomeClass( T t ) { someFnc( std::forward<T>( t ) ); } } int main() { int i = 10; SomeClass<int&> sc( i ); return 0; } My conclusion was (I hope it's correct?) that std::forward always pass along lvalue references and move everything else. Thanks for a very well written book! Best regards, Daniel |
asetofsymbols@gmail.com: Apr 09 05:12AM -0700 I would like to know if main(x){printf("%x",x);} Is a valid C++ program and what number it print... |
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 09 09:06AM -0400 > main(x){printf("%x",x);} > Is a valid C++ program > and what number it print... Not a valid C++ program. V -- I do not respond to top-posted replies, please don't ask |
Juha Nieminen <nospam@thanks.invalid>: Apr 09 03:58PM > main(x){printf("%x",x);} It might have been valid very ancient C (although I don't think it's valid by any *standardization*, but many C compilers will accept it). --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
asetofsymbols@gmail.com: Apr 09 09:00AM -0700 main(x){printf("%x",x);} Seems to me here would print 1 |
asetofsymbols@gmail.com: Apr 09 05:12AM -0700 In this link: http://codegolf.stackexchange.com/questions/12103/generate-a-universal-binary-function-lookup-table There is a problem: How to print using less text possible the matrix 0101010101010101 0011001100110011 0000111100001111 0000000011111111 What would be one C++ solution? |
asetofsymbols@gmail.com: Apr 09 06:48AM -0700 So this is my first try #include<iostream.h> #include<bitset.h> int x; main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} |
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 09 09:50AM -0400 > #include<bitset.h> > int x; > main(){bitset<16>a[]={21845,13107,3855,255};while(x<4)cout<<a[x++]<<"\n";} Does your compiler accept that? How old are the tools you're using?.. Never mind, if they work for you, it's fine. Do you get the result you expect? V -- I do not respond to top-posted replies, please don't ask |
asetofsymbols@gmail.com: Apr 09 07:13AM -0700 main(){char z="\n";bitset<16>a=21845,b=13107,c=3855,r=255;cout<<a<<z<<b<<z<<c<<z<<r<<z;} |
Victor Bazarov <v.bazarov@comcast.invalid>: Apr 09 10:16AM -0400 > main(){char z="\n";bitset<16>a=21845,b=13107,c=3855,r=255;cout<<a<<z<<b<<z<<c<<z<<r<<z;} That's not a valid C++ program. You ought to see it if you run it through a C++ compiler. V -- I do not respond to top-posted replies, please don't ask |
asetofsymbols@gmail.com: Apr 09 08:59AM -0700 #include<iostream.h> #include<bitset.h> #define b(x) bitset<16> x << "\n" main(){cout<<b(21845)<<b(13107)<<b(3855)<<b(255);} |
"Öö Tiib" <ootiib@hot.ee>: Apr 09 03:12AM -0700 On Thursday, 9 April 2015 05:13:45 UTC+3, Stefan Ram wrote: > Somehow, especially C++ seems to attract good > authors. Or maybe C++ programmers need to learn > more than programmers for other languages. Very complex language. For example function's interface. Functions of simplest programming languages have only zero to many "in" parameters and one "out" parameter (return value). C++ function may have template parameters (types and values), return value, by value parameters, by reference or pointer parameters, by rvalue reference parameters plus now also smart pointers and everything has option to be const or volatile qualified, may have default argument values and function may have overloads and specializations. The overloads may be in different namespaces if function arguments are from different namespaces, the template arguments may be deduced, other arguments may be implicitly converted and so on. Most of that variety is only for allowing optimizations that lot of beginner programmers are incapable of considering. |
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment