classFruit { public: // FruitType has been moved inside the class, under the public access specifier // We've also renamed it Type and made it an enum rather than an enum class enumType { apple, banana, cherry };
private: Type m_type {}; int m_percentageEaten { 0 };
public: Fruit(Type type) : m_type { type } { }
Type getType(){ return m_type; } intgetPercentageEaten(){ return m_percentageEaten; }
boolisCherry(){ return m_type == cherry; } // Inside members of Fruit, we no longer need to prefix enumerators with FruitType:: };
嵌套类型 Type 已在类的顶部定义。嵌套类型名称必须先完全定义才能使用,因此通常先定义它们。 Type 的完全限定名称是 Fruit::Type ,而 apple 枚举器的完全限定名称是 Fruit::apple 。
const std::string& getName(){ return m_name; } IDType getId(){ return m_id; } // can use unqualified name within class };
intmain() { Employee john { "John", 1, 45000 }; Employee::IDType id { john.getId() }; // must use fully qualified name outside class
std::cout << john.getName() << " has id: " << id << '\n';
return0; }
嵌套类以及对外部类成员的访问
在 C++ 中,嵌套类无法访问外部(包含)类的 this 指针,因此嵌套类无法直接访问外部类的成员。这是因为嵌套类可以独立于外部类进行实例化(在这种情况下,也就不存在外部类的成员可供访问!)。 嵌套类是外部类的成员,因此它们可以访问外部类中任何在作用域内的私有成员。 嵌套类“可以访问”外部类的所有私有成员(权限足够),但“无法直接使用”外部类的非静态成员(因为没有默认的外部类对象 this)
classouter { public: classinner1; // okay: forward declaration inside the enclosing class okay classinner1{}; // okay: definition of forward declared type inside the enclosing class classinner2; // okay: forward declaration inside the enclosing class okay };
classinner2// okay: definition of forward declared type outside the enclosing class { };
#include<ios>// for std::boolalpha #include<iostream>
template <typename T> classPair { private: T m_first{}; T m_second{};
public: // When we define a member function inside the class definition, // the template parameter declaration belonging to the class applies Pair(const T& first, const T& second) : m_first{ first } , m_second{ second } { }
boolisEqual(const Pair<T>& pair); };
// When we define a member function outside the class definition, // we need to resupply a template parameter declaration template <typename T> bool Pair<T>::isEqual(const Pair<T>& pair) { return m_first == pair.m_first && m_second == pair.m_second; }
public: staticintgetNextID(); // Here's the declaration for a static function };
// Here's the definition of the static function outside of the class. Note we don't use the static keyword here. intIDGenerator::getNextID(){ return s_nextID++; }
intmain() { for (int count{ 0 }; count < 5; ++count) std::cout << "The next ID is: " << IDGenerator::getNextID() << '\n';
classMyClass { private: static Chars generate() { Chars c{}; // create an object c.first = 'a'; // fill it with values however you like c.second = 'e'; c.third = 'i'; c.fourth = 'o'; c.fifth = 'u';
return c; // return the object }
public: staticinline Chars s_mychars { generate() }; // copy the returned object into s_mychars };
intmain() { std::cout << MyClass::s_mychars.third; // print i
return0; }
15.8 — 友元非成员函数
在类体内部,可以使用友元声明 (使用 friend 关键字)来告诉编译器,某个类或函数现在是它的友元。在 C++ 中, 友元是指被授予对另一个类的私有成员和受保护成员的完全访问权限的类或函数(成员或非成员)。这样,一个类就可以选择性地授予其他类或函数对其成员的完全访问权限,而不会影响其他任何内容。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
classAccumulator { private: int m_value { 0 };
public: voidadd(int value){ m_value += value; }
// Here is the friend declaration that makes non-member function void print(const Accumulator& accumulator) a friend of Accumulator friendvoidprint(const Accumulator& accumulator); };
voidprint(const Accumulator& accumulator) { // Because print() is a friend of Accumulator // it can access the private members of Accumulator std::cout << accumulator.m_value; }
const std::string& getName()const & { return m_name; } // & qualifier overloads function to match only lvalue implicit objects, returns by reference std::string getName()const && { return m_name; } // && qualifier overloads function to match only rvalue implicit objects, returns by value