struct, union enum Modern C++ |
C++ 10 . : struct, union enum. C++11 C++17, C++20 .
struct . C++ Code Guidelines, struct , . RGBA-, 2, 3, 4 (, , , ..).
C.2: Use class if the class has an invariant; use struct if the data members can vary independently
struct BookStats
{
std::string title;
std::vector authors;
std::vector tags;
unsigned pageCount = 0;
unsigned publishingYear = 0;
};
class, :
// data
struct Base
{
std::string data;
};
// Base , `: public Base`
struct Derived : Base
{
};
C++ Core Guidelines, struct . "parameter object".
C.1: Organize related data into structures (structs or classes)
, . , 2D 3D 2- 3- , . , GLM (OpenGL Mathematics)
//
// . https://en.wikipedia.org/wiki/Polar_coordinate_system
glm::vec2 euclidean(float radius, float angle)
{
return { radius * cos(angle), radius * sin(angle) };
}
// ,
// .
std::vector TesselateCircle(float radius, const glm::vec2& center, IColorGenerator& colorGen)
{
assert(radius > 0);
// .
// 2.
constexpr float step = 2;
// , .
const auto pointCount = static_cast(radius * 2 * M_PI / step);
// - .
std::vector points(pointCount);
for (unsigned pi = 0; pi < pointCount; ++pi)
{
const auto angleRadians = static_cast(2.f * M_PI * pi / pointCount);
points[pi] = center + euclidean(radius, angleRadians);
}
return TesselateConvexByCenter(center, points, colorGen);
}
C++11 .
struct BookStats
{
std::string title;
std::vector authors;
std::vector tags;
unsigned pageCount = 0;
unsigned publishingYear = 0;
};
:
// ! !
struct BookStats
{
BookStats() : pageCount(0), publishingYear(0) {}
std::string title;
std::vector authors;
std::vector tags;
unsigned pageCount;
unsigned publishingYear;
};
: , :
// C++11, C++14: - pageCount publishingYear
// C++17:
const auto book = BookStats{
u8" ",
{ u8" " },
{ u8"", u8"" },
576,
1965
};
C++11 C++14 boilerplate . C++17 .
, C++11 C++14:
struct BookStats
{
// ! !
BookStats() = default;
// ! !
BookStats(
std::string title,
std::vector authors,
std::vector tags,
unsigned pageCount,
unsigned publishingYear)
: title(std::move(title))
, authors(std::move(authors))
, tags(std::move(authors)) // ;)
, pageCount(pageCount)
, publishingYear(publishingYear)
{
}
std::string title;
std::vector authors;
std::vector tags;
unsigned pageCount = 0;
unsigned publishingYear = 0;
};
C++20 ! , . ? - ?
const auto book = BookStats{
u8" ",
{ u8" " },
{ u8"", u8"" },
1965,
576
};
C11 . C++20 " " ("designated initializer"). ++20.
// C++20
const auto book = BookStats{
.title = u8" ",
.authors = { u8" " },
.tags = { u8"", u8"" },
.publishingYear = 1965,
.pageCount = 576
};
- C++17 . C++ Core Guidelines , . std::variant union.
, union . union . union: union .
// ! !
// Event : type, mouse, keyboard
// mouse keyboard
struct Event
{
enum EventType {
MOUSE_PRESS,
MOUSE_RELEASE,
KEYBOARD_PRESS,
KEYBOARD_RELEASE,
};
struct MouseEvent {
unsigned x;
unsigned y;
};
struct KeyboardEvent {
unsigned scancode;
unsigned virtualKey;
};
EventType type;
union {
MouseEvent mouse;
KeyboardEvent keyboard;
};
};
C++11 union , . union. , : std::string union ( STL).
// ! !
union U
{
unsigned a = 0;
std::string b;
U() { std::memset(this, 0, sizeof(U)); }
};
// - b
U u;
u.b = "my value";
C++17 , variant. variant , union, , STL.
#include
struct MouseEvent {
unsigned x = 0;
unsigned y = 0;
};
struct KeyboardEvent {
unsigned scancode = 0;
unsigned virtualKey = 0;
};
using Event = std::variant<
MouseEvent,
KeyboardEvent>;
enum , . , enum.
, enum . , , m_threadShutdown true, m_threadInitialized false?
// ! !
class ThreadWorker
{
public:
// ...
private:
bool m_threadInitialized = false;
bool m_threadShutdown = false;
};
atomic, Thread*
, enum.
class ThreadWorker
{
public:
// ...
private:
enum class State
{
NotStarted,
Working,
Shutdown
};
// ATOMIC_VAR_INIT atomic .
// compare_and_exchange_strong!
std::atomic = ATOMIC_VAR_INIT(State::NotStarted);
};
, . 4 , , . :
// ! !
void FillSlide(unsigned slideNo)
{
switch (slideNo)
{
case 1:
setTitle("...");
setPictureAt(...);
setTextAt(...);
break;
case 2:
setTitle("...");
setPictureAt(...);
setTextAt(...);
break;
// ...
}
}
, . enum, .
enum SlideId
{
Slide1 = 1,
Slide2,
Slide3,
Slide4
};
enum . :
// ! - !
enum TextFormatFlags
{
TFO_ALIGN_CENTER = 1 << 0,
TFO_ITALIC = 1 << 1,
TFO_BOLD = 1 << 2,
};
unsigned flags = TFO_ALIGN_CENTER;
if (useBold)
{
flags = flags | TFO_BOLD;
}
if (alignLeft)
{
flag = flags & ~TFO_ALIGN_CENTER;
}
const bool isBoldCentered = (flags & TFO_BOLD) && (flags & TFO_ALIGN_CENTER);
, std::bitset
:
enum TextFormatBit
{
TextFormatAlignCenter = 0,
TextFormatItalic,
TextFormatBold,
// ,
// 0,
// 1 .
TextFormatCount
};
std::bitset flags;
flags.set(TextFormatAlignCenter, true);
if (useBold)
{
flags.set(TextFormatBold, true);
}
if (alignLeft)
{
flags.set(TextFormatAlignCenter, false);
}
const bool isBoldCentered = flags.test(TextFormatBold) || flags.test(TextFormatAlignCenter);
. enum constexpr.
Enum.1:
// ! - C99 !
#define RED 0xFF0000
#define GREEN 0x00FF00
#define BLUE 0x0000FF
#define CYAN 0x00FFFF
// , C99,
enum ColorId : unsigned
{
RED = 0xFF0000,
GREEN = 0x00FF00,
BLUE = 0x0000FF,
CYAN = 0x00FFFF,
};
// Modern C++
enum class WebColorRGB
{
Red = 0xFF0000,
Green = 0x00FF00,
Blue = 0x0000FF,
Cyan = 0x00FFFF,
};
++11 scoped enum, enum class
enum struct
. enum :
Enum e = EnumValue1
Enum e = Enum::Value1
, const auto value = static_cast(Enum::Value1)
, enum scoped enum , :
enum class Flags : unsigned
{
// ...
};
, Swift Rust, enum , enum. , enum ,
// enum Swift
enum Barcode {
// upc 4 Int
case upc(Int, Int, Int, Int)
// qrCode String
case qrCode(String)
}
enum std::variant
, C++ C++ 2017. , std::variant
enum , enum . . :
struct AnonymousAccount
{
};
struct UserAccount
{
std::string nickname;
std::string email;
std::string password;
};
struct OAuthAccount
{
std::string nickname;
std::string openId;
};
using Account = std::variant;
:
std::variant
union , , enum class
std::variant
std::variant
, enum class
enum
enum
enum enum class
enum
enum class
, enum
constexpr
-. Code Review . , . , .