[C++기초] 13. C++ 11, 14, 17

INDEX

  1. auto
  2. static_assert
  3. default/delete
  4. final
  5. override
  6. offsetof
  7. 새로운 자료형
  8. nullptr
  9. 고정 폭 소수형
  10. enum class
  11. 헤더에서 초기화하기
  12. 정리

auto

새로운 키워드들

auto

auto로 포인터와 참조 받기

예시 : auto로 포인터 받기

Cat* myCat = new Cat("Coco", 2);
auto myCatPtr = myCat;
//myCat과 동일한 포인터일까요??
//네

왜 포인터와 값 둘 다 auto로 받을까?

예시 : auto로 참조 받기

Cat myCat("Coco", 2);
Cat& myCatRef = myCat;
auto anotherMyCatRef = myCatRef;
//myCat에 대한 참조일까요??
//아니요
Cat myCat("Coco", 2);
Cat& myCatRef = myCat;
auto& anotherMyCatRef = myCatRef;
//myCat에 대한 참조일까요??
//예

예시 : auto로 const받기

const int b = 1;
auto& a = b;
//const를 이어받을까요?
//예

왜 const와 비 const모두 auto로 받을 까?

auto와 함수 반환형

auto는 엄청나게 좋다

auto와 반복자

auto로 템플릿 형 받기

베스트 프랙티스

static_assert

static_assert

assert

static_assert

예시 : 구조체의 크기

Class.h

struct Student
{
	char name[64];
	char id[10];
	int currentSemester;
};

class class
{
public:
	//...
	const Student* GetStudentInfo(const char* name);
};

Class.cpp

const Student* Class::GetStudentInfo(const char* name)
{
	static_assertion(sizeof(Student) == 74, "Student struction size mismatch");
	//이하 코드 생략
}

Result

reusltImage

예시 : version확인하기

Class.h

class Class
{
public:
	const static int Version = 1;
	// ...
}

Main.cpp

#include"Class.h"
static_assert(Class::Version>1, "You need higher version than 1.");

Result

reusltImage

예시 : 배열의 길이

Student.h

class Student
{
public:
	static const int MAX_SCORES = 10;
	int GetScores(int index);
	// ...
private:
int mScor	es[MAX_SCORES];
};

Student.cpp

int Student::GetScores(int index)
{
	static_assert(sizeof(mScores)/sizeof(mScores[0])==MAX_SCORES,
	"The Size of scores vector is not 10");
}

Result

reulstImage

베스트 프랙티스

default/delete

default

default사용 예시

default 사용 X

// Dog.h
class Dog
{
public:
	Dog();
	Dog(std::string name);
private:
	std::string mName;
};
//Dog.cpp
#include "Dog.h"

Dog::Dog()
{
}
Dog::Dog(std::string name)
{
	// 이하 코드 생략
}

defulat 사용 O

//Dog.h
class Dog
{
public:
	Dog() = default;
	Dog(std::string name);
private:
	std::string mName;
};
//Dog.cpp
#include "Dog.h"

//컴파일러가 Dog()를 대신 만들어냄

Dog::Dog(std::string name)
{
	// 이하 코드 생략
}

delete

delete 사용 예시

delete 사용 X

//Dog.h
class Dog
{
public:
	Dog() = default;
	//...
private:
	Dog(const Dog& other);
	//...
}
//Dog.cpp
#include "Dog.h"
int main()
{
	Dog myDog;
	Dog copiedMyDog(myDog); // 에러
	// ...
}

delete 사용 O

//Dog.h
class Dog
{
public:
	Dog() = default;
	Dog(const Dog& other) = delete;
	//...
}
//Dog.cpp
#include "Dog.h"
int main()
{
	Dog myDog;
	Dog copiedMyDog(myDog); // 에러
	// ...
}

default/delete에 관한 베스트 프랙티스

final

final

class Animal final
{
    //...
}
class Dog final : public Animal
{
    //...
}
class Animal
{
    public:
    //함수의 상속(재정의) 막기
    virtual void SetWeight(float weight) final;
    //...
}

override

override

예시 : override 키워드

Animal.h

class Animal
{
public:
	virtual void SetWeight(float weight);
	void PrintAll();
	// ...
};

Dog.h

#include "Animal.h"
class Dog : public Animal
{
public:
	//OK
	virtual void SetWeight(float weight) override;
	
	//컴파일 에러
	virtual void SetWeight(int weight) override;
	
	//컴파일 에러 : 가상 함수가 아님
	void PrintAll() override;
	
	// …
}

offsetof

offsetof

예시 : 멤버들의 상대적 위치 구하기

struct Student
{
	const char* ID;
	const char* Name;
	int CurrentSemester;
};

int main()
{
	std::cout << "ID offset : " << offsetof(Student, ID) << std::endl;
	std::cout << "Name offset : " << offsetof(Student, Name) << std::endl;
	std::cout << "CurrentSemester offset : " << offsetof(Student, CurrentSemester) << std::endl;
	return 0;
}

Result

resultimage

새로운 자료형

새로운 자료형들

nullptr

nullptr

NULL vs nullptr

NULL nullptr
#define NULL type decltype(nullptr) nullptr_t;
숫자 null 포인터 상수
int number = NULL; //OK
int* ptr = NULL; //OK

int anotherNumber = nullptr; //Error
int* anotherPter = nullptr; //OK

예시 : nullptr 사용하기

// Main.cpp
Class* myClass = new Class("COMP3200");

const Student* student = myClass ->GetStudent("Coco");
if(student != nullptr)
{
    std::cout << studnet->GetID() << ":" << student->GetName() << std::endl;
}

고정 폭 소수형

기본 자료형과 바이트 크기

고정 폭 정수형

enum class

enum class

문제 : C-스타일 Enum

Main.cpp

enum eScoreType
{
	Assignment1,
	Assignment2,
	Assignment3,
	Midterm,
	Count,
};

enum eStudyType
{
	Fulltime,
	Parttime,
};

Main.cpp

int main()
{
	escoreType type = Midterm;
	eStudyType studyType = Fulltime;
	
	//에러 안남! 하지만 큰 문제!!
	int num = Assignment3;
	if(type == Fulltime)
	{
		//이하 코드 생략
	}
	return 0;
}

C 스타일은 Enum은 int형이어서 비교하기 시작하면 문제가 발생

해결책 : enum class

Main.cpp

enum class eScoreType
{
	Assignment1,
	Assignment2,
	Assignment3,
	Midterm,
	Count,
};

enum class eStudyType
{
	Fulltime,
	Parttime,
};

Main.cpp

int main()
{
	escoreType score = eScoreType::Midterm;
	eStudyType studyType = eStudyType::Fulltime;
	
	int num = eScoreType::Assignment3; //에러 
	if(score == Fulltime) //에러
{
	//이하 코드 생략
}
return 0;
}

예시 enum class용 정수형 명시하기

//Class.h
#include<cstdint>
enum class eScoreType : uint8_t
{
    Assignment1,
    Assignment2,
    Assignment3,
    Midterm,
    Final = 0x100, // 경고!
};

허나 이렇게 할 수는 없음

컴파일 안되는 예시

for(int i = eScoreType::Assignment1; i<eScoreType::Count; ++i)
{
	// ...
}

컴파일 되는 예시

for(int i = static_cast<int>(eScoreType::Assignment1); i < static_cast<int>(eScoreType::Count); ++i)
{
	// ...
}

헤더에서 초기화하기

마침내 이게 됨!

예시1

class Vector
{
	//...
private:
	int mX = 0; // OK
	int mY = 0; // OK
	const static int mDimension = 2; // OK
	static int mCount = 0; // 에러
}

예시2

class Vector{
	//...
private:
	static int mCount;
};

//vector.cpp
//const static이 아닌 것 때문에 계속 이렇게 해야함
int Vector::mCount = 0;

근데 이걸 써야할까?

정리

새로운 키워드들

새로운 자료형들

보너스