Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
Light-City committed Dec 15, 2019
1 parent e1638bc commit b7dc636
Show file tree
Hide file tree
Showing 9 changed files with 330 additions and 1 deletion.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,16 @@ for(decl:col) {
- [](./modern_++_30/RAII/heap.cpp)
- [](./modern_C++_30/RAII/stack.cpp)
- [RAII](./modern_C++_30/RAII/RAII.cpp)

- [自己动手,实现C++的智能指针](./modern_C++_30/smart_ptr)
- [auto_ptr、scope_ptr](./modern_C++_30/smart_ptr/auto_scope.cpp)
- [unique_ptr](./modern_C++_30/smart_ptr/unique_ptr.cpp)
- [shared_ptr](./modern_C++_30/smart_ptr/shared_ptr.cpp)
- [右值和移动究竟解决了什么问题?](./modern_C++_30/reference)
- [左值与右值](./modern_C++_30/reference/reference.cpp)
- [延长声明周期](./modern_C++_30/reference/lifetime.cpp)
- [引用折叠](./modern_C++_30/reference/collapses.cpp)
- [完美转发](./modern_C++_30/reference/forward.cpp)
- [不要返回本地变量的引用](./modern_C++_30/reference/don'treturnReference.cpp)

### 4.拓展部分

Expand Down
Binary file modified modern_C++_30/.CMakeLists.txt.un~
Binary file not shown.
6 changes: 6 additions & 0 deletions modern_C++_30/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,9 @@ add_executable(auto_scope smart_ptr/auto_scope.cpp)
add_executable(unique_ptr smart_ptr/unique_ptr.cpp)
add_executable(unique_ptr_U smart_ptr/unique_ptr_U.cpp)
add_executable(shared_ptr smart_ptr/shared_ptr.cpp)

add_executable(reference reference/reference.cpp)
add_executable(forward reference/forward.cpp)
add_executable(collapses reference/collapses.cpp)
add_executable(lifetime reference/lifetime.cpp)
add_executable(dontreturnReference reference/don'treturnReference.cpp)
14 changes: 14 additions & 0 deletions modern_C++_30/CMakeLists.txt~
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cmake_minimum_required(VERSION 3.14)
project(Morden_C++)

set(CMAKE_CXX_STANDARD 11)

add_executable(heap RAII/heap.cpp)
add_executable(stack RAII/stack.cpp)
add_executable(RAII RAII/RAII.cpp)
add_executable(RAII_fstram RAII/RAII_fstram.cpp)

add_executable(auto_scope smart_ptr/auto_scope.cpp)
add_executable(unique_ptr smart_ptr/unique_ptr.cpp)
add_executable(unique_ptr_U smart_ptr/unique_ptr_U.cpp)
add_executable(shared_ptr smart_ptr/shared_ptr.cpp)
53 changes: 53 additions & 0 deletions modern_C++_30/reference/collapses.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
//
// Created by light on 19-12-15.
//
#include <iostream>

using namespace std;

template<typename T>
void f(T &&param) {
static_assert(std::is_lvalue_reference<T>::value, "T& is lvalue reference");
cout << "T& is lvalue reference" << endl;
}

template<typename T>
class Widget {
typedef T& LvalueRefType;
typedef T&& RvalueRefType;
public:
void judge() {
static_assert(std::is_lvalue_reference<LvalueRefType>::value, "LvalueRefType & is lvalue reference");
static_assert(std::is_lvalue_reference<RvalueRefType>::value, "RvalueRefType & is lvalue reference");
cout << "LvalueRefType and RvalueRefType is lvalue reference" << endl;
}
void f(LvalueRefType&& param) {

}
};


int main() {
int x;
int &&r1 = 10;
int &r2 = x;
f(r1);
f(r2);

Widget<int &> w;
w.judge();


Widget<int> w1, w2;

auto&& v1 = w1; // v1 is an auto-based universal reference being
// initialized with an lvalue, so v1 becomes an
// lvalue reference referring to w1.

// 不能编译
// decltype(w1)&& v2 = w2; // v2 is a decltype-based universal reference, and
// decltype(w1) is Widget, so v2 becomes an rvalue reference.
// w2 is an lvalue, and it’s not legal to initialize an
// rvalue reference with an lvalue, so
// this code does not compile.
}
55 changes: 55 additions & 0 deletions modern_C++_30/reference/don'treturnReference.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//
// Created by light on 19-12-15.
//

#include <iostream> // std::cout/endl
#include <utility> // std::move
using namespace std;
class Obj {
public:
Obj()
{
cout << "Obj()" << endl;
}
Obj(const Obj&)
{
cout << "Obj(const Obj&)"
<< endl;
}
Obj(Obj&&)
{
cout << "Obj(Obj&&)" << endl;
}
};
Obj simple()
{
Obj obj;
// 简单返回对象;一般有 NRVO
return obj;
}
Obj simple_with_move()
{
Obj obj;
// move 会禁止 NRVO
return std::move(obj);
}
Obj complicated(int n)
{
Obj obj1;
Obj obj2;
// 有分支,一般无 NRVO
if (n % 2 == 0) {
return obj1;
} else {
return obj2;
}
}
int main()
{
cout << "*** 1 ***" << endl;
auto obj1 = simple();
cout << "*** 2 ***" << endl;
auto obj2 = simple_with_move();
cout << "*** 3 ***" << endl;
auto obj3 = complicated(42);
}
45 changes: 45 additions & 0 deletions modern_C++_30/reference/forward.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// Created by light on 19-12-15.
//
#include <iostream>
#include "../RAII/shape.h"

void overloaded( int const &arg ) { std::cout << "by lvalue\n"; }
void overloaded( int && arg ) { std::cout << "by rvalue\n"; }

template< typename t >
/* "t &&" with "t" being template param is special, and adjusts "t" to be
(for example) "int &" or non-ref "int" so std::forward knows what to do. */
void forwarding( t && arg ) {
std::cout << "via std::forward: ";
overloaded( std::forward< t >( arg ) );
std::cout << "via std::move: ";
overloaded( std::move( arg ) ); // conceptually this would invalidate arg
std::cout << "by simple passing: ";
overloaded( arg );
}
void foo(const shape&)
{
puts("foo(const shape&)");
}
void foo(shape&&)
{
puts("foo(shape&&)");
}
template <typename T>
void bar(T&& s)
{
foo(std::forward<T>(s));
}
int main() {
std::cout << "initial caller passes rvalue:\n";
forwarding( 5 );
std::cout << "initial caller passes lvalue:\n";
int x = 5;
forwarding( x );

circle temp;
bar(temp);
bar(circle());

}
108 changes: 108 additions & 0 deletions modern_C++_30/reference/lifetime.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//
// Created by light on 19-12-15.
//

#include <iostream>

using namespace std;

class shape {
public:
shape() { cout << "shape" << endl; }

~shape() {
cout << "~shape" << endl;
}
};

class circle : public shape {
public:
circle() { cout << "circle" << endl; }


~circle() {
cout << "~circle" << endl;
}
};

class triangle : public shape {
public:
triangle() { cout << "triangle" << endl; }


~triangle() {
cout << "~triangle" << endl;
}
};

class rectangle : public shape {
public:
rectangle() { cout << "rectangle" << endl; }

~rectangle() {
cout << "~rectangle" << endl;
}
};

class result {
public:
result() { puts("result()"); }

~result() { puts("~result()"); }
};

result process_shape(const shape &shape1, const shape &shape2) {
puts("process_shape()");
return result();
}


class Base {
public:
Base() {
cout << "Base()" << endl;
}

~Base() {
cout << "~Base()" << endl;
}
};

class Derived : public Base {
public:
Derived() {
cout << "Derived()" << endl;
}

~Derived() {
cout << "~Derived()" << endl;
}
};

string f() { return "abc"; }

void g() {
const string &s = f(); // still legal?
cout << s << endl;
}

Derived factory() {
return Derived();
}

int main() {
process_shape(circle(), triangle());
cout << endl;
// 临时对象延迟
// result &&r = process_shape(circle(), triangle());
// 临时对象延迟只对rvalue有用,而对xvalue无用!
// result &&r = std::move(process_shape(circle(), triangle()));

// const Base &b1 = factory();

Base *b1 = new Derived;
delete b1;
cout<<endl;
Derived d;
Base &b2 =d;
}
43 changes: 43 additions & 0 deletions modern_C++_30/reference/reference.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//
// Created by light on 19-12-14.
//

#include <iostream>
#include <functional>

using namespace std;

// xvalue
int&& f(){
return 3;
}

struct As
{
int i;
};

As&& ff(){
return As();
}

int main() {
// lvalue
int x = 0;
cout << "(x).addr = " << &x << endl;
cout << "(x = 1).addr = " << &(x = 1) << endl;
cout << "(++x).addr = " << &++x << endl;
cout << "(cout << ' ').addr=" << &(cout << ' ') << endl;
cout << "(\"hello\").addr=" << &("hello") << endl;
// rvalue
cout<<true<<endl;
// xvalue
f(); // The expression f() belongs to the xvalue category, because f() return type is an rvalue reference to object type.
static_cast<int&&>(7); // The expression static_cast<int&&>(7) belongs to the xvalue category, because it is a cast to an rvalue reference to object type.
std::move(7); // std::move(7) is equivalent to static_cast<int&&>(7).

ff().i; // The expression f().i belongs to the xvalue category, because As::i is a non-static data member of non-reference type, and the subexpression f() belongs to the xvlaue category.


return 0;
}

0 comments on commit b7dc636

Please sign in to comment.