共用方式為


From C# to C++: Creating a blog demo project – coding style rules

Like I mentioned in my previous post, for the last months I had to change my programming language from C# to C++. To show you some of the things that surprised me in the process, I will write a short series of blog posts to emphasize the scenarios and the issues.

The code samples show a simple project that manages cache entries. Several cache entries can exist in a cache session, and cache sessions are managed by a cache manager. The project was created with Visual Studio 2010. My Visual Studio 2010 has applied a color scheme from https://studiostyles.info/ to make it more attractive.

VS2010-BlogSample-project 

Some notes about the coding style I’m using:

  • Use precompiled header with default VS settings (StdAfx).
  • Use STL. All include statements for STL files are in StdAfx.h (the precompiled header)
 // stdafx.h
#pragma once
#include "targetver.h"

#include <map>
#include <memory>
#include <string>
#include <vector>
…
  • Never include using in header files.
  • Declare all members as private and use properties for accessing them. Private member names start with prefix p.

Coming from a C# background, I came to appreciate the syntactic sugar that lets you write less code and helps with project readability. One of these features is the syntactic sugar for getter and setter accessors of object properties. Well, nothing is lost in C++: a property can be easily defined using __declspec. You can read more about this in this blog post. The properties look like this (snippet from CacheManager.h):

 __declspec(property(get=get_Owner)) std::wstring const & Owner;
std::wstring const & get_Owner() const { return pOwner; }
  • Use typedef whenever needed to make the code easier to read and understand. Example:
 typedef std::map<std::wstring, CacheEntry<std::wstring>> StringCacheEntryMap;
  • Use explicit whenever the constructor has one parameter to avoid implicit type conversion. Example:
 explicit CacheManager(std::wstring const & owner);
  • Prefer passing arguments by reference if at all possible to avoid copy unnecessary operations . Exception: fundamental types and small structures, for which copy is inexpensive.
 void Add(StringCacheEntry const & entry);
  • Always use Resource Acquisition Is Initialization (RAII). Avoid using raw pointers, wrap them in unique_ptr or shared_ptr to avoid memory leaks/corruption.
  • Whenever possible, use move constructors for expensive objects.

In interest of space, the code pasted in the blog entries may be compacted, in which case some of the rules may be abolished.

Comments

  • Anonymous
    October 05, 2010
    All are good points, but it should be clear that the __declspec properties are not C++, but Microsoft extensions.  They don't add anything but confusing semantics when used by other C++ programmers, so I wouldn't recommend using them!

  • Anonymous
    October 05, 2010
    Cory is right but this extension is really useful, Here is a C++ generic implementation: www.codeproject.com/.../cpp_property_indexer.aspx