- Let's talk about multiple inheritance and interfaces. - 13 Updates
- Dynanic Memory - 2 Updates
- 'int' considered dangerous (reprise) - 5 Updates
- "Almost Always Auto" - 2 Updates
- constexpr versus run-time (lack of) efficiency - 2 Updates
- Two questions about "allocator aware container" - 1 Update
Christopher Pisz <nospam@notanaddress.com>: Jan 27 02:16PM -0600 I am having one of those "intellectual discussions" with a coworker whom is making some bold sweeping claims about C++ and C#, which I have to disagree with. It's lighthearted and for fun. I wonder what others say on the topic. He has put forth the following Premise: Multiple inheritance is universally accepted as bad Conclusion: Although the compiler allows you to, you should never use multiple inheritance in C++ Premise: C# enforces an interface to contain no functionality or data in C# Premise: The problems with multiple inheritance can be eliminated because of the former premise. Conclusion: Inheriting from an interface in C# "doesn't count" as multiple inheritance and you _should_ do it I have countered that "just because the compiler doesn't enforce" something doesn't mean I "cannot" or "should not" do it in C++ Premise: I can create an interface in C++ the same as you can in C# Premise: I can inherit from interfaces in the same manner as you can in C# Conclusion: If you can do it I can too and, in fact, I should do it. He disagrees with my final conclusion and I cannot for the life of me fathom why. Am I missing something? Do we need to explore a premise further? What are your thoughts? -- 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 --- |
4ndre4 <4ndre4@4ndre4.com.invalid>: Jan 27 08:40PM On 27/01/2016 20:16, Christopher Pisz wrote: > I am having one of those "intellectual discussions" [...] Rather than discussing in abstract terms, it would be nice to examine a real case, where C# interfaces prove to be a better solution than C++ abstract classes, or vice versa. The only problem with mi that comes to my mind is the classic diamond problem. -- 4ndre4 "The use of COBOL cripples the mind; its teaching should, therefore, be regarded as a criminal offense." (E. Dijkstra) |
Daniel <danielaparker@gmail.com>: Jan 27 12:51PM -0800 On Wednesday, January 27, 2016 at 3:16:36 PM UTC-5, Christopher Pisz wrote: > because of the former premise. > Conclusion: Inheriting from an interface in C# "doesn't count" as > multiple inheritance and you _should_ do it I think the experience of Java and C# is that multiple inheritance of interfaces is very useful, and that multiple inheritance of implementations is not missed, so may as well leave the latter out and avoid the complications. As class I { public: virtual void f() = 0; } class A : public B, public virtual I is directly analogous to inheriting from an interface, I don't see how a Java or C# guy could object. Still, it seems public virtual inheritance is rarely used in C++ code, as compared to interfaces in Java and C#. Perhaps it is because C++ has const, which effectively gives a class two "interfaces", roughly speaking, a mutable and an immutable one. In Java and C#, these would be supported as interfaces. Daniel |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 08:59PM On 27/01/2016 20:51, Daniel wrote: > class A : public B, public virtual I > is directly analogous to inheriting from an interface, I don't see how a Java or C# guy could object. > Still, it seems public virtual inheritance is rarely used in C++ code, as compared to interfaces in Java and C#. Perhaps it is because C++ has const, which effectively gives a class two "interfaces", roughly speaking, a mutable and an immutable one. In Java and C#, these would be supported as interfaces. I think it is fine to use MI as long as only one derivation is public with any others being private which means "implemented-in-terms-of" relationship rather than "is-a" sausages. /Flibble |
scott@slp53.sl.home (Scott Lurndal): Jan 27 09:05PM >fathom why. >Am I missing something? Do we need to explore a premise further? >What are your thoughts? It's all a waste of time. Write programs that solve the stated problem and don't worry about what someone else says is the right or wrong way to do things. There's nothing fundamentally wrong with multiple inheritance. Like any language feature, it can be misused, but that shouldn't preclude its use. Note that an abstract class (pure virtual) is functionally indistinguishable from a Java or C# interface. |
"Öö Tiib" <ootiib@hot.ee>: Jan 27 01:13PM -0800 On Wednesday, 27 January 2016 22:16:36 UTC+2, Christopher Pisz wrote: > fathom why. > Am I missing something? Do we need to explore a premise further? > What are your thoughts? If a feature is simplifying writing working software then we should use it. Run-time dynamic polymorphism in general and multiple inheritance in particular are complex features and so only sometimes simplify writing software. KISS, DRY, YAGNI There are number of other popular programming languages that have multiple inheritance (for example Python, Common Lisp and Scala). C# does not matter. When we program in some other language then it is irrelevant what one can or can not do in C#. |
Christopher Pisz <nospam@notanaddress.com>: Jan 27 03:14PM -0600 On 1/27/2016 2:40 PM, 4ndre4 wrote: > real case, where C# interfaces prove to be a better solution than C++ > abstract classes, or vice versa. The only problem with mi that comes to > my mind is the classic diamond problem. I agree 100% the diamond problem is a problem, but I can just as easily adapt the "An interface does not contain functionality or data" and then the diamond problem is no longer a problem, right? if my C++ "interface" is an abstract class (since we don't have a interface keyword", which contains 100% pure virtuals, then I don't think there is a problem, since D, in the examples, would be forced to implement the the method. But it would be up to the developers to enforce the rules that 'thou shalt only multiple inherit from abstract classes with 100% pure virtual methods', which would be difficult, i agree, to enforce. Doable none the less. -- 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 --- |
Cholo Lennon <chololennon@hotmail.com>: Jan 27 06:36PM -0300 On 01/27/2016 05:16 PM, Christopher Pisz wrote: > fathom why. > Am I missing something? Do we need to explore a premise further? > What are your thoughts? Well, in its last version (8), Java added default implementation for interface methods (aka default methods). Why? IMO, it's because in a lot of situations you need a default behavior (as simple as an empty code for example), but with the mentioned restriction to multiple inheritance of classes , that could not be done. C++ doesn't have that problem (but C# still has it). Also, MI + abstract classes in C++ are more powerful than interfaces with default methods in Java ;-) Regards -- Cholo Lennon Bs.As. ARG |
Jerry Stuckle <jstucklex@attglobal.net>: Jan 27 04:40PM -0500 On 1/27/2016 3:16 PM, Christopher Pisz wrote: > on the topic. > He has put forth the following > Premise: Multiple inheritance is universally accepted as bad Premise: Any premise that says something is "universally accepted" is bad. > Conclusion: Although the compiler allows you to, you should never use > multiple inheritance in C++ Premise: Statements which use "never" are never correct (including this one). > because of the former premise. > Conclusion: Inheriting from an interface in C# "doesn't count" as > multiple inheritance and you _should_ do it An interface in c# is nothing more than a an abstract class with no data members in C++. > Premise: I can create an interface in C++ the same as you can in C# > Premise: I can inherit from interfaces in the same manner as you can in C# > Conclusion: If you can do it I can too and, in fact, I should do it. I agree completely. > fathom why. > Am I missing something? Do we need to explore a premise further? > What are your thoughts? I will, however, say I have see multiple inheritance misused more than used correctly. It's not as bad when the base class has no data members, effectively acting as a C# interface. Having only pure virtual functions makes it even better. But there are times when it can be useful, and I have occasionally used it in the past. But not often. -- ================== Remove the "x" from my email address Jerry Stuckle jstucklex@attglobal.net ================== |
Vir Campestris <vir.campestris@invalid.invalid>: Jan 27 09:43PM On 27/01/2016 20:16, Christopher Pisz wrote: > Premise: Multiple inheritance is universally accepted as bad > Conclusion: Although the compiler allows you to, you should never use > multiple inheritance in C++ I've used it exactly once. There was a feature in the spec which described data of three types. That's OK, except there were consumers which could take types a or b, and those that could take b or c (and some that could take any of them!). We found it easiest to make classes for a, b, and c, and to make an ab class deriving from a and b, and a bc class deriving from b & c. The spec BTW was an open standard. We always wondered what they smoked in the comi9ttee meetings! Andy |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 09:46PM On 27/01/2016 21:05, Scott Lurndal wrote: > Note that an abstract class (pure virtual) is functionally indistinguishable from a > Java or C# interface. In C++ "abstract base class" doesn't mean "interface" it means a class with *at least* one pure virtual function. There is nothing wrong with using the term "interface" when talking about C++ code *if* one is referring to a class which: * contains pure virtual functions with no implementation; * contains trivial inline helper functions which call the pure virtual functions; * does not contain a class invariant. I like to use the term "mixin" for the other type of abstract base class which is basically used to implement the template method design pattern sausages. /Flibble |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 11:06PM +0100 On 1/27/2016 9:16 PM, Christopher Pisz wrote: > Conclusion: Although the compiler allows you to, you should never use > multiple inheritance in C++ I.e. don't use mixin classes. That would be seriously dumb. E.g., class Foo : Non_copyable, // Common with Boost'ed code. , Relops_from_compare< Foo > // Original case for BN trick. , Small_objects_alloc< Foo > // Smth. like that from Loki. { public: friend auto compare( In_<Foo> A, In_<Foo> B ) -> int { ... } }; Cheers & hth., - Alf PS: Since I see no-one has so far mentioned it, to emulate Java/C# inheritance in C++, so that an inherited class can provide an implementation of an interface, one must use virtual inheritance. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 10:12PM On 27/01/2016 22:06, Alf P. Steinbach wrote: > PS: Since I see no-one has so far mentioned it, to emulate Java/C# > inheritance in C++, so that an inherited class can provide an > implementation of an interface, one must use virtual inheritance. Why would you want to emulate Java/C# inheritance in C++? If you are using C++ then use C++. /Flibble |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Jan 27 08:51PM On Wed, 27 Jan 2016 10:00:52 -0500 > > How does it do that? > When the automatic object of type std::vector<...> goes out of scope, > the d-tor is called, and *in it* the dynamic memory (if any) is freed. In case Bill is confused by this and thinks that this is no advantage over static allocation, the rider should be added to the last statement "if you have not moved ownership of the dynamic memory elsewhere". You can move the memory held by a vector to another vector. If you do that the original vector will safely destroy itself when it goes out of scope but not interfere with the ownership of its successor. Chris |
Victor Bazarov <v.bazarov@comcast.invalid>: Jan 27 05:09PM -0500 On 1/27/2016 3:51 PM, Chris Vine wrote: > In case Bill is confused by this and thinks that this is no advantage > over static allocation, the rider should be added to the last statement > "if you have not moved ownership of the dynamic memory elsewhere". I am not sure the additional "rider" is needed given the "(if any)" is already there. But if you feel it makes it /clearer/ to Bill, by all means... > You can move the memory held by a vector to another vector. ... which effectively takes the memory in the given vector and by the time its d-tor executes, there is no dynamic memory *for it* to free. The same result might be achieved by clearing the vector (the ownership of said dynamic memory is optionally returned to the free store). > that the original vector will safely destroy itself when it goes out of > scope but not interfere with the ownership of its successor. > Chris V -- I do not respond to top-posted replies, please don't ask |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 08:09PM 'int' considered dangerous: use a <cstdint> sized integer typedef instead. On a related matter eschewing unsigned integer types is foolish as one should use an unsigned type when dealing with unsigned values. On another related matter the return type of std::uncaught_exceptions is incorrect: it should probably be std::size_t. /Flibble P.S. Sausages. |
Christopher Pisz <nospam@notanaddress.com>: Jan 27 02:17PM -0600 On 1/27/2016 2:09 PM, Mr Flibble wrote: > incorrect: it should probably be std::size_t. > /Flibble > P.S. Sausages. I guess your weekly, "Let's post the same fucking thing again and see if people will argue about it yet again" alarm has gone off. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 08:27PM On 27/01/2016 20:17, Christopher Pisz wrote: >> P.S. Sausages. > I guess your weekly, "Let's post the same fucking thing again and see if > people will argue about it yet again" alarm has gone off. I thought I was in your killfile mate? Judging by the quality of your other posts in this NG recently it would probably benefit a lot of people if you re-added me to it sausages. /Flibble |
Gareth Owen <gwowen@gmail.com>: Jan 27 09:39PM > On a related matter eschewing unsigned integer types is foolish as one > should use an unsigned type when dealing with unsigned values. Two simple rules: i) use an unsigned type when dealing with unsigned values ii) there are (almost) no unsigned values iii) sausages |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Jan 27 09:50PM On 27/01/2016 21:39, Gareth Owen wrote: > i) use an unsigned type when dealing with unsigned values > ii) there are (almost) no unsigned values > iii) sausages ii) and iii) are in conflict as you cannot eat a negative number of sausages. /Flibble |
Jorgen Grahn <grahn+nntp@snipabacken.se>: Jan 27 08:54PM On Wed, 2016-01-27, David Brown wrote: >> what Juha N. wanted to say, too. > That makes more sense, at least regarding Python. But "auto" in C++ is > still static typing - it is just not necessarily explicit typing. Yes, and that's precisely what I was trying to convey above. I'm familiar with the concepts: my first CS course, 26 years ago, used Standard ML, where type inference works just like auto does in C++11. (Just in case you were trying to educate me personally.) ... > So "auto" is not really circumventing either the strong typing system, > or the static typing system - it is merely reducing the verbosity of the > code. But it's not just about verbosity! Someone has to read -- and understand -- the code, too ... more times than someone else has to write it, hopefully. Part of the reason I'm worried is the focus on the writers rather than the readers. /Jorgen -- // Jorgen Grahn <grahn@ Oo o. . . \X/ snipabacken.se> O o . |
David Brown <david.brown@hesbynett.no>: Jan 27 10:15PM +0100 On 27/01/16 21:54, Jorgen Grahn wrote: > familiar with the concepts: my first CS course, 26 years ago, used > Standard ML, where type inference works just like auto does in C++11. > (Just in case you were trying to educate me personally.) No, I was just trying to get the details clear, especially on the differences between C++ auto and Python typing. (I agree that C++ auto and ML are similar or even identical - but I am not familiar enough with ML languages to be precise.) > But it's not just about verbosity! Someone has to read -- and > understand -- the code, too ... more times than someone else has to > write it, hopefully. That is why reducing verbosity is a good thing (as long as it does not reduce clarity). You don't have to write out the type explicitly if it is not needed, nor do you have to read it if it does not add anything to your understanding of the code. > Part of the reason I'm worried is the focus on the writers rather than > the readers. That is my focus is not on writers when saying that auto is good at reducing verbosity. But I fully agree with you that being able to /read/ the code easily is more important than being able to write it easily. |
"Öö Tiib" <ootiib@hot.ee>: Jan 27 11:59AM -0800 On Wednesday, 27 January 2016 03:13:15 UTC+2, Alf P. Steinbach wrote: > efficient compile time evaluation when one knows the arguments allow > that, or reasonably efficient checking for data known only at run time. > Is there any way to /automate/ that choice? Following example may be of use: #include <iostream> #include <type_traits> template<typename T> constexpr typename std::remove_reference<T>::type makeprval(T && t) { return t; } #define isprvalconstexpr(e) noexcept(makeprval(e)) int main(int argc, char *argv[]) { int a = 1; const int b = 2; constexpr int c = 3; const int d = argc; std::cout << isprvalconstexpr(a) << std::endl ; std::cout << isprvalconstexpr(b) << std::endl ; std::cout << isprvalconstexpr(c) << std::endl ; std::cout << isprvalconstexpr(d) << std::endl ; } It outputs: 0 1 1 0 That can be perhaps used to select the algorithm? I think I took it from SO answer of Johannes Schaub and there was something about limitations but don't remember what question it was. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Jan 27 09:39PM +0100 On 1/27/2016 8:59 PM, Öö Tiib wrote: > That can be perhaps used to select the algorithm? I think I took it > from SO answer of Johannes Schaub and there was something about > limitations but don't remember what question it was. That's pure genius. :) But then, his trick for accessing private members was also pure genius. Cheers, & thanks, - Alf |
Daniel <danielaparker@gmail.com>: Jan 27 10:11AM -0800 On Wednesday, January 27, 2016 at 12:31:27 PM UTC-5, Alf P. Steinbach wrote: > > They do :-) > Uhm, not sure how you arrive at that conclusion, so not sure what to > explain. You're right. I was asking about these constructors vector(const vector&, const Allocator&); vector(vector&&, const Allocator&); I took your statement "there are no such constructors" to mean that such constructors did not exist, but I see you were just pointing out that they were not by definition copy or move constructors. My question was whether these were required in order for a container to be "allocator aware", and as Öö Tiib replied, the answer is yes. Thanks, Daniel |
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