Tag Info

New answers tagged

4

The Rule of Five is ex-idiomatic. It was only idiomatic for a very brief period before the Rule of Zero. The principle of the Rule of 3 became obsolete when writing your own resource-handling classes became obsolete, which is when your compiler supports rvalue references. If you implement in terms of unique_ptr, which you can for virtually every resource ...


4

Move semantics were added to C++11 in such a way that the "rule of 3" is still valid and sufficient to avoid the pitfalls that it is meant to avoid (althogh there are better ways in most situations by applying the "rule of 0"). There are also no additional pitfalls added to the language that the "rule of 5" would help you avoid. In that sense, the rule of 5 ...


0

I prefer a different phrasing of the rule of three, which seems more reasonable, which is "if your class needs a destructor (other than an empty virtual destructor) it probably also needs a copy constructor and assignment operator." Specifying it as a one way relationship from the destructor makes a few things clearer: It doesn't apply in cases where you ...


2

Member variables are variables are a "has a" relationship (the rectangle has a width). If the object does not have the variable then it should be passed into it to be used where required, if it's related to the object itself then it should be stored in the object. A quick way to test the relation could be seeing how much that object uses the variable. If ...


5

This is an example of operator precedence not giving quite the results you expect. The example has the code *s.pd = 9; which is equivalent to the following: *(s.pd) = 9; You query why it isn't written as s->pd = 9; but this is equivalent to (*s).pd = 9; That is, the code in the example dereferences the value of pd that is a member of s, ...


0

What's the difference between a functor and a lambda? The way the code you write looks! A lambda is just a functor written in-line so to avoid a bit of boring boilerplate (replacing it with less boilerplate). So asking why C++ didn't have this feature is missing the point of what the feature really is. What extra functionality do you gain from a lamdba that ...


10

C++ had function objects from 1983 onwards; they took/takes care of many examples where people now use lambdas (and use lambdas in other languages). In fact, a C++ lambda is probably best understood as a simplified notation for defining and immediately using a function object.


5

What a closure does, in essence, is abstract over the lifetime of variables. Manual memory management OTOH, requires the programmer to be aware of the lifetime of variables. But, how can you be aware of something that is abstracted away from you? Closures are fundamentally incompatible with manual memory management. Reconciling the two is very hard, and ...


3

C++ did not have an ISO standard until well after it was first created. Much of its early life was fragmented, with compilers all working differently to the point of being source-incompatible at times. The first C++ standard was C++98, with relatively minor updates in the C++03 standard. The primary goal of these standards was to take the "wild west" of C++ ...


7

Weak compilers, large scope, existing library weaknesses, and potentially negative library interactions. First, it was very hard for implementations to support all of C++98, and only occurred many years after the Standard shipped. Adding even more features in would only have made this worse. C# doesn't have this problem because C# 1.0/2.0 are very easy to ...


0

Interoperability is usually achieved by transferring data Generally, you can think each language being it's own separate program. This is not always the case though... Some examples: Sending sql queries to a database using json_encode() in php to encode a data structure into it's string representation, which then can be decoded by java script. Exposing ...


1

Bill Door gave some good examples where the "main program" is written in C or C++, and a scripting language is included for customization, But there is also a common, but different scenario, where the "main program", written in some "scripting language" (whatever people have in mind when they use that word) is extended by modules written in C or C++. For ...


3

Yes, it is perfectly normal to use old style code, provided the scope of your project is well known or is limited. If you plan on extending your program or project OOP is one way to go, because you can maintain and extend your code seamlessly, on the other hand if you planned it and have come to a conclusion that you are never going to plan extensibility of ...


24

C++ is not "just" an OO language, it is a multi-paradigm language. So it allows you to decide for or against OO programming, or to mix them both. Using OO techniques adds more structure to your program - from which you will benefit when your program reaches a certain size or complexity. This additional structure, however, comes for the price of additional ...


10

How do professional programmers make judgement call on whether to go for OOP or not? It would be really helpful for me. For me, there are two decision points. First, sometimes it will be obvious at the beginning. There will be lots of similar types that all share common methods that differ widely in their implementation details. For example, I was ...


4

In many cases, when you see multiple languages used together, you will find that one is a compiled language and the other is a scripting language. The compiled language is typically C/C++, but can be many other languages (Haskell, Erlang, Java, etc). The compiled language provides the base application. The base provides an interface to the underlying ...


0

If you can easily identify where the objects that should survive indefinitely are allocated, once possibility would be to allocate them using an alternative allocation mechanism so that either they don't show up in a valgrind leak report or just appear to be a single allocation. In case you're not familiar with the idea, here's an article on how to impotent ...


1

The key here is this: While I can see that, it is also true that our project does need accurate memory debugging, as I already found memory corruption, double frees and uninitialised variables. This pretty much directly implies that your codebase is cobbled together from nothing more than hope and string. Competent C++ programmers do not have ...


1

One good approach would be to narrow down the discussion with your colleagues by means of classification. Given a large code base, certainly there is not one single reason but rather multiple, (identifiable) reasons for long living objects. Examples: Long living objects which are not referenced by anyone (real leaks). It is a programming logic error. Fix ...


4

Add a switch to the server process that can be used during valgrind measurements that will release all of the memory. You can use this switch for testing. The impact will be minimal during normal operations. We had a long running process that would take several minutes to releases 1000’s of objects. It was much more efficient to just exit and let them die. ...


0

IMHO, the lifetimes of these objects should never just be made and left to die when the system shuts down. This reeks of global variables, which we all know are bad bad bad bad bad. Especially in the age of smart pointers, there is no reason to do this other than laziness. But more importantly, it adds a level of technical debt to your system that someone ...


-2

well the above answers are completely right. Actually many teachers do so. reason is that some might have not updated them to C++ knowledge..... or for some it might have become habit. once a particular syntax fits itself into our hands, it become very difficult to get rid of it.....especially if it is not wrong syntax. We become habitual of writing that ...


5

This is one of the differences between C and C++. In C, structure names are completely separate from other names and you must use the struct keyword to tell the compiler to look for the name of a structure. Another way to put it is that the struct keyword is actually part of the name of the structure. When designing C++, this was changed and the use of the ...


4

There is no clean and safe way to quickly/efficiently "kill" a thread. You can signal to the thread object that it needs to terminate, but the thread needs to be written in such a way that it checks for this and then cleans itself up. Otherwise, you can end up with partially-completed operations, memory leaks, resource leaks, deadlocks, and all manner of ...


2

OpenGL is a 3D graphics API. It provides APIs describe a 3D scene and render it to a framebuffer and ultimately display it on a screen. The primitives it has are vertex lists, triangle lists, normal vector lists, etc. n.b. 2D is a special case of 3D; IIRC OpenGL doesn't have explicit 2D support (i.e. sprites and bit blit) OpenCV is a computer vision (CV) ...


2

I've never used OpenCV, but AFAIK, it is very different from OpenGL. OpenGL is a C API constructed around a LOT of global state (hence why it is often called a state machine), while OpenCV exposes a more Object Oriented C++ interface, with heavy use of templates. OpenGL is intended to be a thin abstraction layer of the graphics hardware, so it can also be ...


3

In older C++ (pre C++11), there is no significant difference between your two implementations of operator+. Either the copy constructor gets called when you invoke the operator or when you make the explicit copy inside the operator. In this case, it is more of a personal preference/coding guideline issue which one to choose. With the introduction of move ...


1

I would go for the take by value approach. Maybe in this case it does not matter as the Vec3i is cheap to copy, but in general, this would allow the lhs value to be constructed from rvalue with a move constructor, thus removing any copying of objects.


2

This is probably a bit opinionated, but if I see two equivalent alternatives in code, I typically prefer the one with less "noise". In your case, the difference of the second alternative to the first is only in additional "noise" - technical code which does not improve the readability in any way. That is why I would prefer the first variant. or should I ...


5

Creating a compiler that is written in the same language that it compiles is called bootstrapping. The wikipedia article describes a number of ways that a compiler can be bootstrapped. Given your restriction that you only have a post-4.8 G++ source code and no pre-built binaries for your target platform (no existing C++ compiler), then bootstrapping the G++ ...


13

This is actually a well-known concept called bootstrapping. Basically, there exists, somewhere, a minimal C codebase to build a version of GCC that's capable of building the current GCC codebase. Self-hosting languages have been doing things like that for decades.


3

A field you add to a structure for the purpose of error checking is often called a dog tag (I think it's so called after Code Complete - Steve McConnel). A dog tag is used to check for corrupted memory: when you allocate a variable put a value that should remain unchanged into its tag file; when you use the structure check the tag's field value (if the ...


1

You can use the pimpl idiom, and provide methods to iterate over the container. In the header : typedef People* PeopleIt; class AddressBook { public: AddressBook(); PeopleIt begin(); PeopleIt begin() const; PeopleIt end(); PeopleIt end() const; private: struct Imp; std::unique_ptr<Imp> pimpl; }; In the source : struct ...


0

if you want exact implementation of functions from std::vector, use private inheritance as below and control what is exposed. template <typename T> class myvec : private std::vector<T> { public: using std::vector<T>::begin; using std::vector<T>::end; using std::vector<T>::push_back; }; Edit: This is not ...


1

One could provide member functions: size_t Count() const People& Get(size_t i) Which allow access without exposing implementation details (like contiguity) and use these within an iterator class: class Iterator { AddressBook* addressBook_; size_t index_; public: Iterator(AddressBook& addressBook, size_t index=0) : ...


2

If iteration is all you need, then perhaps a wrapper around std::for_each would suffice: class AddressBook { public: AddressBook(); template <class F> void for_each(F f) const { std::for_each(begin(people), end(people), f); } private: std::vector<People> people; };


3

This is a simple C++ rule: objects that are more complex that a simple integer, pointer, etc (not a native type) have constructors and destructors. When an instance of such object is declared by value inside a scope, its constructor gets automatically called. When the scope it was declared is exited, the destructor gets automatically called. So take this ...


18

allow iteration without leaking the internals is exactly what the iterator pattern promises. Of course that is mainly theory so here is a practical example: class AddressBook { using peoples_t = std::vector<People>; public: using iterator = peoples_t::iterator; using const_iterator = peoples_t::const_iterator; AddressBook(); iterator ...


2

Ok, I would never in a million years do this, but you could do something like this: Force auto inclusion of this: // forcebanned.h #define for "You must include banned.h" Then add this: // mybanned.h #undef for #include banned.h But don't do that. Better is to make the inclusion of banned.h a coding standard, and rely on code reviews to catch it. If ...


3

What you need to understand is that the C++ standard library quite possibly has the worst implementation of futures conceivable by man. What C++ does is little more than a weak wrapper around a semaphore. Most future implementations encourage use of callback lambdas extensively, to chain several futures together asynchronously using then, and allow you to ...


7

However, though versions of this text appear all over on the internet my question is not completely answered by this explanation. Though it may be implied, since global variables always seem to be static it would be nice to have a straight out answer. If you didn't explicitly create it, you don't need to explicitly destroy it. Let's just remove some of ...


1

I guess the way you have solved the problem of having a private Constructor might just serve your need. I don't see any creational design pattern fit this requirement, but you should be fine without one here.


4

Python is a dynamically-typed language. This has two important consequences: The compiler is unable to reject certain kinds of logical error at compile time which would be caught by a C++ compiler Because the types of some (even most) variables cannot be determined at compile time, operations on those variables must be implemented by dynamically ...


9

Programs which require real-time number crunching (such as digital audio workstations or video players) have what I call a "computational threshold." What that means is that the choice of programming language can matter when there is not enough hardware horsepower to satisfy the necessary computational load, if the language itself is consuming a substantial ...


1

It is notably an implementation issue, not a language one (however the typing is different in the languages). Pedantically, both Python & C++ are Turing-complete languages with a lot of bindings to external libraries, so every program you could write in Python could be rewritten in C++ and vice versa. On Linux, /usr/bin/python (a.k.a. cpython) is a ...


3

Generally, what is the preferred method for the problem described above, or which method is preferred in which cases? The prefered method looks like this: class Object { ... }; std::istream& operator>>(std::istream& in, Object& obj) { /* classic "in" operator*/ } Client code (1): Object o; if(std::cin >> o) { // do ...


3

Don't confuse "exception" with "rare" The main point of exceptions and exception handling is keeping different types of code apart: The code that provides the main functionality (the "happy path" code) Everything else: The code that handles all those 973 other cases where not everything has worked out wonderfully and precisely to your main ...


1

[Note: This question already has an accepted answer, and this answer only adds more arguments to it - but it is too long for a comment]. One such problem is deciding if a method should be part of the class or not. I have found a very good guideline offered by A. Stepanov on this question: He basically says that objects should be constructed from fully ...


4

It depends. If you need to calculate once, and use million times, then the answer is obvious: the first case wins. If you need to calculate every time, or quite often, then pick what you prefer. Your function doesn't read from a file, and has no slow operations, so it will not make a huge difference. Avoid premature optimization. When optimizing, it is ...


2

On the newMNumber create a unique_ptr and use the .get() method to return a raw pointer. Wouldn't this defeat the purpose of using smart pointers? No, no it would not. The point of using smart pointers is about controlling who deletes the object, not who observes the object. It's perfectly fine under the smart pointer paradigm to observe the ...



Top 50 recent answers are included