new feature
VS Support For C++11/14/17 Features (Modern C++)
1.auto:自动类型(deduce actual type from its initializer)
#include <map>
#include <vector>
int myAdd(int x, int y)
{
return x + y;
}
typedef int (*MYADDFUN)(int, int);
void feature_auto_test()
{
auto a = 8LL;
auto f = new MYADDFUN;
*f = myAdd;
auto b = (*f)(1, 2);
TRACE(_T("%d\n"), b);
std::map<int, int> map;
map.insert(std::make_pair(11, 1));
map.insert(std::make_pair(21, 2));
for (auto it = begin(map); it != end(map); ++it)
{
TRACE(_T("(%d, %d)\n"), it->first, it->second);
}
}
2.nullptr:可以给指针类型和bool类型,但不可以给intigral type
#include <memory>
int fun1(std::shared_ptr<int> p)
{
if (nullptr == p)
return 1;
return *p + 1;
}
void feature_nullPtr_test()
{
int* p1 = NULL;
int* p2 = nullptr;
if (p1 == p2)
{
TRACE(_T("equal\n"));
}
TRACE(_T("%d\n"), fun1(nullptr));
bool b = nullptr;
if (!b)
{
TRACE(_T("false\n"));
}
int p3 = nullptr;//error: A native nullptr can only be converted to bool or,
//using reinterpret_cast, to an **integral type**
}
3.Range-based for loops:collection/array
void feature_rangeBasedForLoop_test()
{
std::map<std::string, std::vector<int>> map;
std::vector<int> v;
v.push_back(1);
v.push_back(2);
v.push_back(3);
map["one"] = v;
for (const auto& item : map)
{
TRACE("%s:\n", item.first.c_str());
for (auto v : item.second)
{
TRACE(" %d\n", v);
}
}
int arr[] = { 1,2,3 };
for (int& e : arr)
{
TRACE("%d\n", e * e);
}
}
4.identifier - overwrite : indicate that a method is supposed to be an override of a virtual method in a base class 如果基类没有完全相同的虚函数,就会报错
class B
{
public:
virtual void f(short) {std::cout << "B::f" << std::endl;}
};
class D : public B
{
public:
virtual void f(int) override {std::cout << "D::f" << std::endl;}//error:
//'D::f' : method with override specifier 'override' did not override any
//base class methods
};
5.identifier - final : indicate that a derived class shall not override a virtual method 限制方法被派生类重载
class B
{
public:
virtual void f(int) {std::cout << "B::f" << std::endl;}
};
class D : public B
{
public:
virtual void f(int) override final {std::cout << "D::f" << std::endl;}
};
class F : public D
{
public:
virtual void f(int) override {std::cout << "F::f" << std::endl;}
};
D::f重载了B::f, 但因为D::f有final, 所以F::f没有重载基类的方法。
6.Strongly-typed enums : enum class
传统的枚举是没有封装起来的,可以直接访问,而enum class则不再直接暴露枚举值
enum class Weekdays{Monday,Tuesday,Wednesday};
Weekdays ev = Weekdays::Tuesday;
7.Smart pointers : unique_ptr/shared_ptr/weak_ptr
unique_ptr: should be used when ownership of a memory resource does
not have to be shared (it doesn’t have a copy constructor), but
it can be transferred to another unique_ptr (move constructor
exists).shared_ptr: should be used when ownership of a memory resource should
be shared (hence the name).weak_ptr: holds a reference to an object managed by a shared_ptr, but
does not contribute to the reference count; it is used to break
dependency cycles (think of a tree where the parent holds an owning
reference (shared_ptr) to its children, but the children also must
hold a reference to the parent; if this second reference was also an
owning one, a cycle would be created and no object would ever be
released).
7.1.Smart pointer : std::unique_ptr/std::move/std::unique_ptr.get()
int fun2(int* p)//raw pointer
{
if (nullptr == p)
return 1;
return *p + 1;
}
void feature_uniquePtr_test()
{ //std::unique_ptr //smart pointer
//std::unique_ptr.get() //observing pointer(raw pointer)
//std::move //transfer ownership
std::unique_ptr<int> p1(new int(42));
std::unique_ptr<int> p2 = std::move(p1);
int nRet = 0;
if (p1)
{
nRet = fun2(p1.get());
}
(*p2)++;
if (p2)
{
nRet = fun2(p2.get());
}
}
7.2.Smart pointer : std::shared_ptr/std::make_shared
int fun3(int* p)//raw pointer
{
if (nullptr == p)
return 0;
(*p)++;
return *p;
}
int fun4(std::shared_ptr<int> p)
{
if (nullptr == p)
return 0;
(*p) *= 2;
return (*p);
}
void feature_sharedPtr_test()
{
std::shared_ptr<int> p1(new int(88));//auto p1 = std::make_shared<int>(88);
std::shared_ptr<int> p2 = p1;
int nRet = fun3(p1.get());//89
nRet = fun4(p2);//178
}
make_shared<T> is a non-member function and has the advantage of allocating memory
for the shared object and the smart pointer with a single allocation,
as opposed to the explicit construction of a shared_ptr via the contructor,
that requires at least two allocations. In addition to possible overhead,
there can be situations where memory leaks can occur because of that.
7.3.Smart pointer : std::weak_ptr/lock/expired/reset
void feature_weakPtr_test()
{
auto p = std::make_shared<int>(88);
std::weak_ptr<int> wp = p;
auto sp1 = wp.lock();//convert to shared_ptr
TRACE(_T("%d\n"), *sp1);
wp.reset(); //release resource, convert to null weak_ptr object
if (wp.expired())//return true if resource no longer exists
{
TRACE(_T("expired\n"));
auto sp2 = wp.lock();//lock on an expired weak_ptr return empty shared_ptr
if (nullptr == sp2)
{
TRACE(_T("nullptr\n"));
}
}
}