I know that there are some other questions about c++ refactoring, but none satis
ID: 654634 • Letter: I
Question
I know that there are some other questions about c++ refactoring, but none satisfies my needs.
I have a background in java and python programming, but now I'm approaching C++. I've read (and absolutely love) books about agile coding, tdd, refactoring, etc. The first that comes in my mind is "Clean Code". From this I have learned a lot of things: keep my functions short, keep my classes short, keep names of variables/classes consistent etc..
I like very much this way of working: first resolve the problem, then refactor in small functions (and one function does only one thing), adding subclasses, etc.
I strongly believe that this way of working is made easy from modern IDE: add file, rename function, rename classes, etc..
I'm now coding in c++ with cmake inside QtCreator. All of those things are more difficult. Even adding a file is "more difficult" (I have to generate one header file, one source file, add them to cmakelist.txt, run again cmake, etc). Thinking about renaming files (I have to manually change all includes) or some strong refactoring methods that in Java with Eclipse has no cost now gives me a headache.
I mean.. it is not "difficult" in the meaning that are "hard task", but the human mind is kind of lazy: if I can do other easiest way..
In Java with some modern IDE like Eclipse.. refactor is the fun parts, some clicks and voil
Explanation / Answer
TL;DR: C++ have an old compilation model and hard to process syntax (because highly contextual) which makes tools hard to make but they exists. Refactoring is a bit harder to do in C++ but it's just a bit slower to do than in other languages.
I think you just need some additional information about C++ itself and related tools. Let's see:
There ARE refactoring tools for C++ that would help in renaming files etc. One example is the Visual Studio plugin Visual Assist X. I think Eclipse and other editors do have some refactoring tools too. They are unperfect but have been very useful for me for years. Now, where it is less useful is when you don't organize your code in a way which is usual and "forced" in other languages like Java or Python or C# because...
C++ suffer a lot from using a very old compilation model. It makes some kind of code (header-heavy) slower to compile, it makes hard to locate library headers, etc. The compilation have to be understood to fully understand why depending on the kind of library you use or develop, you will not organize your sources directories the same ways. Anyway, this makes tools hard to build around it. In particular because macros are the way we import modules, which means it's all copy-pasting.
Defining header + source is classic if you are defining most class systems, but it's far from being the normal/only way of doing things in c++. For example a lot of Boost libraries are header-only which mean there is no associated cpp file and you can't test the code without adding cpp files to compile it (headers don't really exists for the compiler, see the compilation model).
Also, C++ syntax is highly contextual which means a tool that is able to refactor C++ correctly should have the same kind of information about the processed source code than a compiler. That is one reason for the efforts of LLVM to provide libraries to parse and have a correct model of C++ code, which can then be used by tools implementations. Howver, only few tools so far are usable but we expect a lot of refactoring tools to emerge from LLVM effort in the coming years.
Having a modern, structured and well-defined module system like in Java, C#, Python and Ruby is clearly superior for compilation speed but more importantly to help the compiler know what is a module and how modules are linked together. The C++ ISO standard committee is working on such a modern Module system to be added into the C++17 version if it is ready then. The point is that the issue is acknowledged and being solved. The work on this is being done into the LLVM/Clang compiler.
Beware that CMake is an meta-build-system. What I mean here is that it's independant on the edition tool you use (I use it with Visual Studio for example) and add, indeed, an indirection into the process of adding/removing/renaming file. As C++ don't have any standard build system, it is one such a tool, but it is a meta description of your project. For example, if I use directly Visual Studio or QtCreator default project formats, it is far easier to change file names as you can do it directly into the editor. But indeed these project files are not compatible with other editors/platforms, which is why you use CMake to be sure you will be able to generate project files for a variety of development setups. Basically, if you don't use CMake, refactoring is faster, but you loose cross-editor/cross-platform build-system features.
All that being said, my experience so far with C++ refactoring is that if you have something like VAssistX it is enough to do most of it. Renaming files indeed longer to do correctly than in other languages, but it's not that long. That being said, it would be helpful if any change to a C++ project would be faster to check, which is why a module system is really necessary. Hopefully you don't work yet with code that takes an hour or more to compile, in which case the impact on refactoring is devastating as people don't want to modify too much the code because it's making them insane to have to wait. This is a hard problem for the C++ community and again work is in progress to fix it. But it will take years.