Modern_Effective_C - 8BitsCoding/RobotMentor GitHub Wiki
์ฐธ๊ณ ์ฌ์ดํธ์ ์ค๋ช ์ด ์ ๋ง ์ข์...
๋ด๊ฐ ํ์ํ ๋ถ๋ถ๋ง ๋ณ๋๋ก ์ ๋ฆฌํจ.
- Initializer list
- auto type
- foreach
- nullptr
- enum class
- static_assert
- Delegating Constructor
- Override (for virtual function)
- final
- Compiler Generated Default Constructor
- delete
- constexpr
- New String Literals
- lambda function
// C++03
int arr[4] = {3, 2, 4, 5};
vector<int> v;
v.push_back(3);
v.push_back(2);
v.push_back(4);
v.push_back(5);
// ๋งค๋ฒ ์ด๋ ๊ฒ ์ ์ธํ๊ธฐ ๋ถํธ
vector<int> v = {3, 4, 1, 9};
// ๋ด๊ฐ ์์ฑ์๋ฅผ ๋ง๋ค ์ ์๋ค.
#include <initializer_list>
class boVector {
vector<int> m_vec;
public:
beVector(const initializer_list<int>& v) {
for(initializer_list<int>::iterator itr = v.begin(); itr != v.end(); ++itr)
m_vec.push_back(*itr);
}
}
boVector v = {0, 2, 3, 4};
boVector v2{0, 2, 3, 4};
// ์๋ฒฝํ๊ฒ ๋์ผํจ.
std::vector<int> vec = {2, 3, 4, 5};
// C++ 03
for(std::vector<int>::iterator it = vec.begin(); it != vec.end(); it++)
m_vec.push_back(*it);
// C++ 11
for(auto it = vec.begin(); it != vec.end(); it++)
m_vec.push_back(*it);
// C++ 03
for(vector<int>::iterator itr = v.begin(); itr != v.end(); itr++)
cout << (*itr);
// C++ 11
for(int i : v) {
cout << i;
}
for(auto& i : v) {
i++;
}
void foo(int i) { cout << "foo_int" << endl; }
void foo(char * pc) { cout << "foo_char*" << endl; }
int main() {
// C++03
foo(NULL); // Ambiguity(๋ชจํธ)
// C++11
foo(nullptr); // call foo(char*)
}
// C++ 03
enum apple {green_a, red_a};
enum orange {big_o, small_o};
apple a = green_a;
orange o = big_o;
if (a == o)
cout << "์ค๋ฅ"
else
cout << "์ ์"
// C++ 11
enum class apple {green, red};
enum class orange {big, small};
apple a = apple::green;
orange o = orange::big;
// run-time assert
assert(myPointer != NULL)
// Compile time assert(C++11)
static_assert(sizeof(int) == 4);
class dog {
public:
dog() { ... }
dog(int a) { dog(); doOtherThings(a); }
};
// C++ 03
class dog {
init() { ... };
public:
dog() { init(); }
dog(int a) { init(); doOtherTings(); }
};
// C++ 11
class dog {
public:
dog() { ... }
dog(int a) : dog() { doOtherTings(); }
};
// C++ 03
class dog {
virtual void fn_A(int);
virtual void fn_B() const;
};
class yellowdog : public dog {
virtual void fn_A(float); // ์๋ก์ด ํจ์๊ฐ ์์ฑ๋จ
virtual void fn_B(); // ์ญ์ ์๋ก์ด ํจ์๊ฐ ์์ฑ๋จ
};
// C++ 11
class dog {
virtual void fn_A(int);
virtual void fn_B() const;
void fn_C();
};
class yellowdog : public dog {
virtual void fn_A(float) override; // Error(no function to override)
virtual void fn_B() override; // Error
void fn_C() override; // Error
};
class dog final {
// no class can be derived from dog
};
class dog {
virtual void bark() final;
// No class can override bark()
}
// C++ 03
class dog {
dog(int age) {}
};
dog d1; // Error (compiler will not generate the default constructor)
// C++ 11
class dog {
dog(int age);
dog() = defualt;
};
// C++ 03
class dog {
dog(int age) {}
};
dog a(2);
dog b(3.0); // 3.0 is converted from double to int
a = b; // Compiler generated assignment operator
// C++ 11
class dog {
dog(int age) {}
dog(double) = delete;
dog& operator=(const dog&) = delete;
};
int arr[6];
int A() { return 3; }
int arr[A() + 3]; // Compile Error
// C++11
constexpr int A() { return 3; }
// Force the computation to happen at compile time.
int arr[A()+3];
// Create an array of size 6
// Write faster program with constexpr
constexpr int cubed(int x) { return x * x * x; }
int y = cubes(1789);
// computed at compile time
// C++ 03
char * a = "string";
// C++ 11
char * a = u8"string"; // to define an UTF-8 string
char16_t * b = u"string"; // to define an UTF-16 string
char32_t * c = U"string"; // to define an UTF-32 string
char * d = R"string \\"; // to define raw string.
(์ฐธ๊ณ ) UTF-8 : ์ ๋์ฝ๋๋ฅผ ์ํ ๋ฌธ์ ์ธ์ฝ๋ฉ ๋ฐฉ์ ์ค ํ๋
ํ ๋ฌธ์๋ฅผ ๋ํ๋ด๊ธฐ ์ํด์ 1~4bytes๊น์ง๋ฅผ ์ฌ์ฉ
(์ฐธ๊ณ 2) ์ ๋์ฝ๋ vs ๋ฉํฐ๋ฐ์ดํธ :
์ ๋์ฝ๋ - ์์คํค ์ฝ๋ ๋ฟ๋ง ์๋๋ผ ํ๊ธ, ์ผ์ด๋ฑ์ ๋ชจ๋ ํ ๋ฌธ์ํ๋ก ํํ
๋ฉํฐ๋ฐ์ดํธ - ์์คํค ์ฝ๋ ๋ฌธ์ํ์ ์ถ๊ฐํ์ฌ ๋ค๋ฅธ ๋ฌธ์ํํ
cout << [](int x, int y{return x+y}(3,4)) << endl;
// Output : 7
auto f = [](int x, int y){return x+y;};
cout << f(3, 4) << endl;
// Output : 7
ํจ์๋ฅผ ๋งค๊ฐ๋ณ์๋ก ๋ฃ์ ์ ์๋ค.
template<typename func>
void filter(func f, vector<int> arr) {
for(auto i : arr) {
if(f(i))
cout << i << " ";
}
}
int main() {
vector<int> v = {1, 2, 3, 4, 5, 6};
filter([](int x) {return (x>3);}, v); // Output: 4 5 6
filter([](int x) {return (x>2 && x<5);}, v); // Output : 3 4
int y = 4;
filter([&](int x) {return (x>y);}, v);
// Output : 5 6
// Note : [&] tells compiler that we want variable capture(lambda can access local variable)
}
- Moving semantics
- Perfect forwarding
// What is rvalue reference?
int main() {
int a = 5;
// a is a lvalue
int& b = a;
// b is a lvalue reference
int&& c;
// c is a rvalue reference
}
void printInt(int& i) {cout << "lvalue reference: " << i << endl;}
void printInt(int&& i) {cout << "rvalue reference: " << i << endl;}
int a = 5;
printInt(a); // Call lvalue reference : printInt(int& i)
printInt(5); // Call rvalue reference : printInt(int&& i)
class boVector {
int size;
double * arr_;
public:
boVector(const boVector& rhs) {
size = rhs.size;
arr_ = new double[size];
for(int i = 0; i < size; i++) { arr_[i] = rhs.arr_[i]; }
}
~boVector() {delete arr_;}
};
void foo(boVector v);
void foo_by_ref(boVector& v);
boVector createBoVector(); // Creates a boVector
void main() {
boVector reuseable = createBoVector();
foo(resuable);
// Copy constructor๊ฐ ํธ์ถ๋๋ค.
foo_by_ref(createBoVector());
// createBoVector()์ ๋ฆฌํด์ r-value์ด๋ค.
// Move constructor๊ฐ ํธ์ถ๋๋ค.
// r-value์ฉ constructor๊ฐ ํ์ํ๋ค.
}
class boVector {
int size;
double * arr_;
public:
boVector(const boVector& rhs) {
size = rhs.size;
arr_ = new double[size];
for(int i = 0; i < size; i++) { arr_[i] = rhs.arr_[i]; }
}
boVector(const boVector&& rhs) { // Move constructor
size = rhs.size;
arr_ = rhs.arr_;
rhs.arr_ = nullptr;
}
~boVector() {delete arr_;}
};
์ด๋ ๊ฒ ํ๋ ์ด์ ๋ ์ ์๊ฐํด๋ณด๋ฉด ์์ง๋ง
l-value ๋ณต์ฌ๋ ๋งค๋ฒ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ ํ ๋นํ๋ฉฐ ์์์ ์๋ชจ๊ฐ ์๋ ๋ฐ๋ฉด r-value ๋ณต์ฌ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ฌ ํ ๋นํ์ง ์๊ณ ์ฌํ์ฉํ๊ธฐ์ ์์์ ์๋ชจ๊ฐ ๋ ํ๋ค.