Tag Info

Hot answers tagged

59

From The Design and Evolution of C++ - Bjarne Stroustrup - Addison-Wesley (ISBN 0-201-54330-3) - chapter 13.2.3: The curious = 0 syntax was chosen over the obvious alternative of introducing a new keyword pure or abstract because at the time I saw no chance of getting a new keyword accepted. Had I suggested pure, Release 2.0 would have shipped without ...


19

If you add a virtual destructor to a class: in most (all?) current C++ implementations, every object instance of that class needs to store a pointer to the virtual dispatch table for the runtime type, and that virtual dispatch table itself added to the executable image the address of the virtual dispatch table is not necessarily valid across processes, ...


13

Any class that has any virtual methods should have a virtual destructor. Otherwise, the superclass's destructor will not be called if the object is deleted through a pointer to the child class. In other words, if the keyword virtual exists in the class declaration, you must at least have this: virtual ~Class() {}; In theory, you don't need to do this if ...


9

A similar question has been asked on Stack Overflow. In the accepted answer, Nicol Bolas points out that it isn't in the standard because it has to be proposed and voted on. In the way that C++ works, people write proposals for changes, which are voted on. However, he points out that it's a convenience function and doesn't add that much value over the ...


9

Before grabbing into the "modern C++" bag, let us keep things simple and start with some classic, language agnostic techniques. One solution is to make a function of the form void myfunc(int i,bool upward) { identical_lines identical_lines identical_lines if(upward) first_for_specific_line else ...


8

Nearly all CPUs have a single instruction that will return the modulus of a value. For instance, consider this program: int main() { int i = 10; return i % 3; } If I compile this on my Intel OS X machine using g++ -S, the result will be some boilerplate and this: movl $3, %eax movl $0, -4(%rbp) movl $10, -8(%rbp) movl -8(%rbp), %ecx ...


8

Because making a function virtual incurs a non-zero runtime cost. Part of the philosophy of C++ is "you only pay for what you use"; i.e. you don't pay the cost of a virtual function unless you've explicitly asked for it by writing virtual in your code. As for why it incurs that runtime cost, the short answer is that a father pointer by itself does not say ...


7

Your algorithm is O(N²) - if you have 1000 elements in your vector and the first 100 are null, it will run the while loop 100 times, each repositioning up to 999 elements. In implementation, you would use two iterators, one which you read from and one which you write to. If the read element is null, do not write it, otherwise write it back and increment. ...


7

Yes, so the function can change thing. In general, it is best to put the behavior on the object itself. In other words, prefer this: class Thing { public: void do_stuff() { ... } }; ...to this: void do_stuff( Thing & thing ) { ... } However, both examples are perfectly valid and usable. One good example of a non-member non-const ...


7

If you take the source code from JasperReports and translate that literally to C++, then you are creating a derived work and you are bound by the license that the original work is released under. For a translation of a work under the LGPL license, this means that you must distribute your translation also under the LGPL (which means also providing your source ...


7

Whenever you feel an urge to inspect the dynamic type of your polymorphic objects at run-time, you should question your design. This is true for any object-oriented language I know. The visitor pattern can be of great help in avoiding to bother with the dynamic type of an object. Some people seem to think that cheating around type inspection by adding a ...


7

Why c++ not set all destructors virtual by default? Cost of extra storage and call of virtual method table. C++ is used for system, low-latency, rt programming where this could be burden.


7

In which case I should NOT use virtual destructors? For a concrete class which doesn't want to be inherited. For a base class without polymorphic deletion. Either clients should not be able to delete polymorphically using a pointer to Base. BTW, In which case should use virtual destructors? For a base classes with polymorphic deletion.


5

Start from data structures. Write functions operating on those data structures. If you want encapsulation, do it at the level of modules, not objects. If you want polymorphism, use higher-order functions, not virtual dispatch. That’s about it. OOP as practiced is not a significant departure from procedural programming. It’s primarily a set of reasonable ...


5

At what level of complexity does the platform start to matter and the program won't just run anywhere? Basically anything non-trivial. If you write a non-trivial program, you will end up accidentally depending on a compiler-specific way that it orders overloads, looks up names, and other complex things. Furthermore, practically all non-trivial ...


5

There are reasons why you might want to change things in place. One reason might be performance: it's expensive to make all those new objects for output. There are reasons why you might write things in a more functional, immutable style. One reason is referential transparency. Another is easier and more reliable concurrency and function composition. ...


4

One thing the Visitor Pattern does that is often not talked about, is enabling to choose which side of the Expression Problem you want to tackle. So, what is the Expression Problem? It refers to the basic problem of extensibility: our programs manipulate data types using operations. As our programs evolve, we need to extend them with new data types and new ...


4

It's perfectly fine to #include additional headers in .cpp files that are not included in the corresponding .h. In fact, you should always do so if the header is not required in the .h, because that potentially speeds up compilation of anything that depends on your .h but not on your .cpp. See this classic Guru of the Week for some tips on minimizing ...


4

Use operator overloading if it improves code clarity and maintainability. Sometimes it helps clarity and maintainability: a + b is shorter and clearer than a.addTo(b), it makes it easier to write generic algorithms (e.g., templates) and change data types, etc. Sometimes it hurts clarity and maintainability: overloaded operators can be surprising ...


4

I'd say if your Java devs regularly program in C# and vice versa, they might have some argument for making them look the same (slightly easier to read). But even then, differences can be useful enough to trump reading ease. I for one like to use same-line-open-brackets in JavaScript to remind my brain at all times that the code I'm looking at is not C#. ...


4

You have to use a blocking construct on a per-request basis. This is called Futures (programming) Each request will have its own Future. Once the request processing is started (possibly in a separate pool of threads, as you have described), the caller will be blocked on the Future's fulfillment, or failure. When the result arrives, the Future is ...


4

In general, it turns out very badly if objects of the same level know about each other. Once objects know about each other they are tied, or coupled to each other. This makes them hard to change, hard to test, hard to maintain. It works out much better if there is some object "above" that knows about the two and can set the interactions between them. The ...


3

This answer is specific to C++ (as indicated by the tag on this question). Most other compiled languages (outside C and C++) do not have such consideration, because in those languages there is no benefit in moving configurations to compile-time. Outside of C and C++, conditional compilation is greatly discouraged or simply unsupported. Also, C and C++ ...


3

Unsurprisingly, this depends on the purpose of the function and the nature of the type it's retrieving/extracting. But it's usually easy to make a choice based on the properties of the type. 1) The value is a primitive such as int or char Then the choice is effectively between: int x = getInt(); and int x; setInt(x); I would strongly prefer returning ...


3

Yes, having exactly one getter/setter pair per private flag is a code smell. If you aren't providing a simple interface to hide some implementation details, you're not benefiting very much from using a class. My main concrete suggestion would be to represent the internal state in a way that makes "bad states" theoretically impossible. For instance: class ...


3

There is a case for different styles for each language - it helps you remember that you're writing something different, and thus will help to prevent some subtle errors due to language similarities (ie where you are still thinking Java techniques when writing C# code and vice-versa). It can slow you down a little when switching, but frankly - this is a ...


3

From a logical (non-technical) point of view, there is no advantage. Any plain C / C++ code can be wrapped within suitable "library construct". After such wrapping, the matter of "whether this is more advantageous than that" becomes a moot question. From a speed point-of-view, C / C++ should allow the library construct to generate code that is as efficient ...


3

There are two aspects to the const in C++: logical constness: When you create a variable and point a const pointer or reference to it, the compiler simply checks that you don't modify the variable via the const pointer or reference, directly or indirectly. This constness can be cast away with a const_cast<>. As such, the following code is perfectly ...


2

The destructor should be declared virtual if inheritance is involved and the derived class needs to be destroyed in a specific way that differs from the base class.


2

Yes, some times it is very convenient to be able to locally modify a pass-by-value argument to a function. For example, the argument might be a reference to a node of a linked list, and within the function you may want to traverse the list, so you will want to be doing node = *(node.next);. So, ill-advised? definitely not, in my opinion. There exist ...



Only top voted, non community-wiki answers of a minimum length are eligible