当前位置: 首页 > news >正文

南京中小企业网站制作电子商务网站建设试题答案

南京中小企业网站制作,电子商务网站建设试题答案,腾讯企业邮箱网页版登录官网,网站建设公司的小程序选择什么7.1 定义抽象数据类型 7.1.1 类的基本概念 在C中#xff0c;类是用户定义的类型#xff0c;提供了一种将数据和操作这些数据的函数#xff08;成员函数#xff09;组合在一起的方法。类定义了对象的属性和行为#xff0c;通过实例化类来创建对象。 7.1.2 定义类 定义类…7.1 定义抽象数据类型 7.1.1 类的基本概念 在C中类是用户定义的类型提供了一种将数据和操作这些数据的函数成员函数组合在一起的方法。类定义了对象的属性和行为通过实例化类来创建对象。 7.1.2 定义类 定义类时需要指定类的名称并在类体内声明数据成员和成员函数。类定义的一般形式如下 class ClassName { public:// 成员函数声明returnType functionName(parameterList);private:// 数据成员声明dataType memberName; }; 示例代码 #include iostream #include stringclass Person { public:// 成员函数声明void setName(const std::string name);std::string getName() const;private:// 数据成员声明std::string name; };// 成员函数定义 void Person::setName(const std::string name) {this-name name; }std::string Person::getName() const {return name; }int main() {Person person;person.setName(Alice);std::cout Name: person.getName() std::endl;return 0; } 在这个示例中定义了一个Person类包含数据成员name和成员函数setName及getName。 7.1.3 成员函数 成员函数是类的函数可以访问类的成员变量。成员函数可以在类内部声明在类外部定义。成员函数的定义需要使用类名和作用域运算符::。 示例代码 #include iostream #include stringclass Book { public:void setTitle(const std::string title);std::string getTitle() const;private:std::string title; };void Book::setTitle(const std::string title) {this-title title; }std::string Book::getTitle() const {return title; }int main() {Book book;book.setTitle(C Primer);std::cout Title: book.getTitle() std::endl;return 0; } 在这个示例中定义了一个Book类包含数据成员title和成员函数setTitle及getTitle。 7.1.4 构造函数 构造函数是用于创建类对象并初始化数据成员的特殊成员函数。构造函数的名称与类名相同没有返回类型。 示例代码 #include iostream #include stringclass Car { public:Car(const std::string brand, int year); // 构造函数声明void display() const;private:std::string brand;int year; };Car::Car(const std::string brand, int year) : brand(brand), year(year) {} // 构造函数定义void Car::display() const {std::cout Brand: brand , Year: year std::endl; }int main() {Car car(Toyota, 2020);car.display();return 0; } 在这个示例中定义了一个Car类包含数据成员brand和year并通过构造函数初始化这些成员。 7.1.5 类的接口和实现 类的接口是指类的公共成员包括公共数据成员和公共成员函数。类的实现是指类的私有成员和成员函数的定义。通过将接口和实现分离可以提高代码的可读性和可维护性。 示例代码 #include iostream #include stringclass Animal { public:void setName(const std::string name);std::string getName() const;private:std::string name; };void Animal::setName(const std::string name) {this-name name; }std::string Animal::getName() const {return name; }int main() {Animal animal;animal.setName(Elephant);std::cout Animal: animal.getName() std::endl;return 0; } 在这个示例中定义了一个Animal类包含数据成员name和成员函数setName及getName。 重点与难点分析 重点 类的定义掌握类的基本结构和定义方法理解类的成员变量和成员函数的声明与定义。构造函数理解构造函数的作用和定义方法掌握构造函数的初始化列表的使用。类的接口和实现理解类的接口和实现的概念掌握将类的接口与实现分离的方法。 难点 成员函数的定义初学者需要通过实践掌握成员函数在类外部定义的方法理解作用域运算符::的使用。构造函数的初始化列表掌握构造函数初始化列表的语法和使用方法理解其在类对象初始化中的作用。 练习题解析 练习7.1定义一个Student类包含数据成员name和age以及相应的构造函数和成员函数。 示例代码 #include iostream #include stringclass Student { public:Student(const std::string name, int age);void display() const;private:std::string name;int age; };Student::Student(const std::string name, int age) : name(name), age(age) {}void Student::display() const {std::cout Name: name , Age: age std::endl; }int main() {Student student(John, 21);student.display();return 0; } 练习7.2编写一个Rectangle类包含成员函数area和perimeter用于计算矩形的面积和周长。 示例代码 #include iostreamclass Rectangle { public:Rectangle(double width, double height);double area() const;double perimeter() const;private:double width;double height; };Rectangle::Rectangle(double width, double height) : width(width), height(height) {}double Rectangle::area() const {return width * height; }double Rectangle::perimeter() const {return 2 * (width height); }int main() {Rectangle rect(5.0, 3.0);std::cout Area: rect.area() std::endl;std::cout Perimeter: rect.perimeter() std::endl;return 0; } 练习7.3定义一个Circle类包含数据成员radius并实现计算圆周长和面积的成员函数。 示例代码 #include iostream #include cmathclass Circle { public:Circle(double radius);double circumference() const;double area() const;private:double radius; };Circle::Circle(double radius) : radius(radius) {}double Circle::circumference() const {return 2 * M_PI * radius; }double Circle::area() const {return M_PI * radius * radius; }int main() {Circle circle(5.0);std::cout Circumference: circle.circumference() std::endl;std::cout Area: circle.area() std::endl;return 0; } 练习7.4编写一个BankAccount类包含数据成员balance实现存款和取款的成员函数。 示例代码 #include iostreamclass BankAccount { public:BankAccount(double initialBalance);void deposit(double amount);void withdraw(double amount);double getBalance() const;private:double balance; };BankAccount::BankAccount(double initialBalance) : balance(initialBalance) {}void BankAccount::deposit(double amount) {balance amount; }void BankAccount::withdraw(double amount) {if (amount balance) {balance - amount;} else {std::cout Insufficient balance. std::endl;} }double BankAccount::getBalance() const {return balance; }int main() {BankAccount account(1000.0);account.deposit(500.0);account.withdraw(200.0);std::cout Balance: $ account.getBalance() std::endl;return 0;} 总结与提高 本节总结 学习了类的定义和基本概念掌握了成员函数和数据成员的声明与定义方法。理解了构造函数的作用和定义方法掌握了构造函数初始化列表的使用。通过示例代码和练习题加深了对类的接口和实现的理解和应用。 提高建议 多练习类的定义与使用通过编写各种包含类的程序熟悉类的定义和使用方法提高代码的组织性和可读性。深入理解构造函数通过实践掌握构造函数的初始化列表和重载构造函数的方法理解其在对象初始化中的作用。封装类的接口与实现在编写类时合理设计类的接口与实现提高代码的可维护性和安全性。 7.2 访问控制与封装 7.2.1 访问控制 访问控制用于限制类成员的访问权限。C 提供了三种访问控制级别 public公有成员可以被类的任何部分访问也可以被类外部的代码访问。protected受保护成员可以被类的成员和派生类访问但不能被类外部的代码访问。private私有成员只能被类的成员访问不能被派生类和类外部的代码访问。 示例代码 #include iostreamclass Base { public:int publicVar; protected:int protectedVar; private:int privateVar; };class Derived : public Base { public:void accessMembers() {publicVar 1; // 可以访问protectedVar 2; // 可以访问// privateVar 3; // 无法访问编译错误} };int main() {Base base;base.publicVar 1; // 可以访问// base.protectedVar 2; // 无法访问编译错误// base.privateVar 3; // 无法访问编译错误return 0; } 在这个示例中Base类有公有、受保护和私有成员Derived类可以访问公有和受保护成员但不能访问私有成员。 7.2.2 封装 封装是将数据和操作数据的函数绑定在一起并将细节隐藏起来只暴露接口。通过封装可以保护数据不被外界直接访问和修改增强代码的安全性和可维护性。 示例代码 #include iostream #include stringclass Employee { public:void setName(const std::string name);std::string getName() const;void setSalary(double salary);double getSalary() const;private:std::string name;double salary; };void Employee::setName(const std::string name) {this-name name; }std::string Employee::getName() const {return name; }void Employee::setSalary(double salary) {this-salary salary; }double Employee::getSalary() const {return salary; }int main() {Employee emp;emp.setName(John Doe);emp.setSalary(50000);std::cout Employee: emp.getName() , Salary: $ emp.getSalary() std::endl;return 0; } 在这个示例中Employee类通过公有成员函数对私有数据成员进行封装保护数据成员不被直接访问。 7.2.3 友元 友元Friend是可以访问类的私有和受保护成员的非成员函数或其他类。友元关系不是传递的也不能继承。 友元函数 #include iostreamclass Box {friend void printBox(const Box box); // 声明友元函数 public:Box(double length, double width, double height) : length(length), width(width), height(height) {}private:double length;double width;double height; };void printBox(const Box box) {std::cout Length: box.length , Width: box.width , Height: box.height std::endl; }int main() {Box box(10.0, 5.0, 3.0);printBox(box);return 0; } 在这个示例中printBox函数是Box类的友元可以访问Box类的私有成员。 友元类 #include iostreamclass Engine {friend class Car; // 声明友元类 public:Engine(int horsepower) : horsepower(horsepower) {}private:int horsepower; };class Car { public:Car(const std::string model, int horsepower) : model(model), engine(horsepower) {}void showDetails() const {std::cout Model: model , Horsepower: engine.horsepower std::endl;}private:std::string model;Engine engine; };int main() {Car car(Toyota, 150);car.showDetails();return 0; } 在这个示例中Car类是Engine类的友元类可以访问Engine类的私有成员。 重点与难点分析 重点 访问控制掌握public、protected和private访问控制的用法和区别理解其在类中的应用。封装理解封装的概念掌握通过公有成员函数访问私有数据成员的方法。友元了解友元函数和友元类的定义和用法理解其在访问私有和受保护成员中的作用。 难点 友元的使用初学者需要通过实践掌握友元的定义和使用方法理解友元关系的非传递性和不可继承性。封装的实现通过实践理解封装的概念掌握在类中实现封装的方法提高代码的安全性和可维护性。 练习题解析 练习7.5定义一个Laptop类包含私有数据成员brand和price并实现公有成员函数设置和获取这些成员的值。 示例代码 #include iostream #include stringclass Laptop { public:void setBrand(const std::string brand);std::string getBrand() const;void setPrice(double price);double getPrice() const;private:std::string brand;double price; };void Laptop::setBrand(const std::string brand) {this-brand brand; }std::string Laptop::getBrand() const {return brand; }void Laptop::setPrice(double price) {this-price price; }double Laptop::getPrice() const {return price; }int main() {Laptop laptop;laptop.setBrand(Dell);laptop.setPrice(999.99);std::cout Brand: laptop.getBrand() , Price: $ laptop.getPrice() std::endl;return 0; } 练习7.6编写一个Box类包含私有数据成员length、width和height并实现友元函数计算盒子的体积。 示例代码 #include iostreamclass Box {friend double calculateVolume(const Box box); // 声明友元函数 public:Box(double length, double width, double height) : length(length), width(width), height(height) {}private:double length;double width;double height; };double calculateVolume(const Box box) {return box.length * box.width * box.height; }int main() {Box box(10.0, 5.0, 3.0);std::cout Volume: calculateVolume(box) cubic units std::endl;return 0; } 练习7.7定义一个Library类包含私有数据成员name和books书籍数量并实现友元类Librarian能够访问和修改Library类的私有成员。 示例代码 #include iostream #include stringclass Library {friend class Librarian; // 声明友元类 public:Library(const std::string name, int books) : name(name), books(books) {}private:std::string name;int books; };class Librarian { public:void setLibraryName(Library library, const std::string name) {library.name name;}void addBooks(Library library, int count) {library.books count;}void showLibrary(const Library library) const {std::cout Library: library.name , Books: library.books std::endl;} };int main() {Library library(Central Library, 1000);Librarian librarian;librarian.showLibrary(library);librarian.addBooks(library, 200);librarian.showLibrary(library);librarian.setLibraryName(library, City Library);librarian.showLibrary(library);return 0; } 练习7.8编写一个Account类包含私有数据成员balance实现存款、取款和显示余额的公有成员 函数并确保封装性。 示例代码 #include iostreamclass Account { public: Account(double initialBalance); void deposit(double amount); void withdraw(double amount); void displayBalance() const;private: double balance; };Account::Account(double initialBalance) : balance(initialBalance) {}void Account::deposit(double amount) {balance amount; }void Account::withdraw(double amount) {if (amount balance) {balance - amount;} else {std::cout Insufficient balance. std::endl;} }void Account::displayBalance() const {std::cout Balance: $ balance std::endl; }int main() {Account account(1000.0);account.deposit(500.0);account.withdraw(200.0);account.displayBalance();account.withdraw(2000.0); // 测试不足余额情况return 0; } 总结与提高 本节总结 学习了访问控制的基本概念掌握了public、protected和private访问控制的使用方法。理解了封装的概念掌握了通过公有成员函数访问私有数据成员的方法提高了代码的安全性和可维护性。通过示例代码和练习题理解了友元函数和友元类的定义和使用方法掌握了友元在访问私有和受保护成员中的作用。 提高建议 多练习访问控制的使用通过编写各种包含不同访问控制级别的类熟悉public、protected和private的使用方法理解其在类设计中的作用。深入理解封装的实现通过实践掌握封装的概念合理设计类的接口与实现提高代码的安全性和可维护性。掌握友元的使用在编写复杂类时合理使用友元函数和友元类提高类之间的协作性和灵活性。 7.3 类的其他特性 7.3.1 类成员再探 在前面的章节中我们学习了如何定义类的成员函数和数据成员。这一小节将进一步探讨类成员的高级特性和使用方法包括初始化列表、成员初始化顺序和常量成员。 初始化列表 初始化列表用于在构造函数体之前初始化类成员。使用初始化列表可以提高代码的效率和可读性尤其是在初始化常量成员和引用成员时。 示例代码 #include iostream #include stringclass Person { public:Person(const std::string name, int age) : name(name), age(age) {}void display() const {std::cout Name: name , Age: age std::endl;}private:std::string name;int age; };int main() {Person person(Alice, 30);person.display();return 0; } 在这个示例中初始化列表用于初始化name和age成员。 成员初始化顺序 成员初始化的顺序按照它们在类中声明的顺序进行而不是在初始化列表中的顺序。因此确保在编写初始化列表时遵循声明顺序。 示例代码 #include iostreamclass Example { public:Example(int a, int b) : b(b), a(a) {} // 初始化顺序依然是 a, bvoid display() const {std::cout a: a , b: b std::endl;}private:int a;int b; };int main() {Example ex(1, 2);ex.display();return 0; } 尽管初始化列表中b在a之前实际初始化顺序仍然是a先于b。 常量成员 常量成员在类定义时被声明为const必须通过初始化列表进行初始化且初始化后不能修改。 示例代码 #include iostreamclass Circle { public:Circle(double radius) : radius(radius) {}void display() const {std::cout Radius: radius std::endl;}private:const double radius; };int main() {Circle circle(5.0);circle.display();return 0; } 在这个示例中常量成员radius通过初始化列表进行初始化。 7.3.2 返回*this的成员函数 返回*this的成员函数允许我们将类的成员函数串联起来调用链式调用。这种方法在实现流操作符重载和构造复杂对象时非常有用。 示例代码 #include iostream #include stringclass Person { public:Person setName(const std::string name) {this-name name;return *this;}Person setAge(int age) {this-age age;return *this;}void display() const {std::cout Name: name , Age: age std::endl;}private:std::string name;int age; };int main() {Person person;person.setName(Alice).setAge(30);person.display();return 0; } 在这个示例中setName和setAge函数返回*this允许链式调用这些成员函数。 7.3.3 友元再探 友元friend是可以访问类的私有和受保护成员的非成员函数或其他类。友元关系不是传递的也不能继承。 类之间的友元关系 类之间可以建立友元关系使一个类能够访问另一个类的私有成员。 示例代码 #include iostreamclass Engine;class Car { public:void displayEngine(const Engine engine); };class Engine {friend class Car; // Car 是 Engine 的友元类 public:Engine(int horsepower) : horsepower(horsepower) {}private:int horsepower; };void Car::displayEngine(const Engine engine) {std::cout Engine horsepower: engine.horsepower std::endl; }int main() {Engine engine(150);Car car;car.displayEngine(engine);return 0; } 在这个示例中Car类是Engine类的友元可以访问Engine类的私有成员。 成员函数作为友元 一个类的成员函数可以成为另一个类的友元从而访问该类的私有成员。 示例代码 #include iostreamclass Building;class Architect { public:void design(Building building); };class Building {friend void Architect::design(Building building); // Architect 的 design 函数是 Building 的友元 public:Building(int floors) : floors(floors) {}private:int floors; };void Architect::design(Building building) {building.floors 10; // 访问 Building 的私有成员 }int main() {Building building(5);Architect architect;architect.design(building);return 0; } 在这个示例中Architect类的成员函数design是Building类的友元可以访问Building类的私有成员。 函数重载和友元 友元函数可以重载通过定义不同的参数列表实现不同的功能。 示例代码 #include iostreamclass Rectangle;class Geometry { public:double calculateArea(const Rectangle rect);double calculateArea(const Rectangle rect, double height); };class Rectangle {friend double Geometry::calculateArea(const Rectangle rect); // Geometry 的 calculateArea 是 Rectangle 的友元friend double Geometry::calculateArea(const Rectangle rect, double height); public:Rectangle(double width, double height) : width(width), height(height) {}private:double width;double height; };double Geometry::calculateArea(const Rectangle rect) {return rect.width * rect.height; }double Geometry::calculateArea(const Rectangle rect, double height) {return rect.width * height; }int main() {Rectangle rect(5.0, 3.0);Geometry geom;std::cout Area: geom.calculateArea(rect) std::endl;std::cout Area with height 4.0: geom.calculateArea(rect, 4.0) std::endl;return 0; } 在这个示例中Geometry类的calculateArea函数被重载并且是Rectangle类的友元。 友元声明和作用域 友元声明可以在类的任意位置进行但友元关系仅在声明的类内有效。友元关系不能被继承也不是传递的。 示例代码 #include iostreamclass B;class A {friend class B; // B 是 A 的友元类 public:A(int value) : value(value) {}private:int value; };class B { public:void displayA(const A a) {std::cout As value: a.value std::endl;} };class C : public B {};int main() {A a(100);B b;C c;b.displayA(a); // B 可以访问 A 的私有成员// c.displayA(a); // 编译错误C 不能访问 A 的私有成员return 0; } 在这个示例中B是A的友元类可以访问A的私有成员但继承自B的C不能继承友元关系。 重点与难点分析 重点 类成员再探掌握初始化列表、成员初始化顺序和常量成员的定义和使用方法。返回*this的成员函数理解返回*this的成员函数的用途掌握链式调用的实现方法。友元再探理解类之间的友元关系、成员函数作为友元、函数重载和友元、友元声明和作用域的概念和应用。 难点 成员初始化顺序初学者需要理解成员初始化顺序的重要性避免初始化列表中的顺序与成员声明顺序不一致。友元的使用掌握友元函数和友元类的使用方法理解其在类设计中的作用避免滥用友元导致类的耦合度过高。 练习题解析 练习7.14定义一个Vehicle类包含常量成员maxSpeed并通过初始化列表进行初始化。 示例代码 #include iostreamclass Vehicle { public:Vehicle(int speed) : maxSpeed(speed) {}void display() const {std::cout Max Speed: maxSpeed km/h std::endl;}private:const int maxSpeed; };int main() {Vehicle car(180);car.display();return 0; } 练习7.15编写一个Book类包含返回*this的成员函数setTitle和setAuthor实现链式调用。 示例代码 #include iostream #include stringclass Book { public:Book setTitle(const std::string title) {this-title title;return *this;}Book setAuthor(const std::string author) {this-author author;return *this;}void display() const {std::cout Title: title , Author: author std::endl;}private:std::string title;std::string author; };int main() {Book book;book.setTitle(C Primer).setAuthor(Lippman);book.display();return 0; } 练习7.16定义两个类Point和Circle建立它们之间的友元关系使Circle类可以访问Point类的私有成员。 示例代码 #include iostreamclass Point {friend class Circle; // Circle 是 Point 的友元类 public:Point(int x, int y) : x(x), y(y) {}private:int x, y; };class Circle { public:Circle(int radius) : radius(radius) {}void display(const Point center) {std::cout Center: ( center.x , center.y ), Radius: radius std::endl;}private:int radius; };int main() {Point center(5, 5);Circle circle(10);circle.display(center);return 0; } 练习7.17编写一个Vector类并定义友元函数重载加法运算符实现两个向量的相加。 示例代码 #include iostreamclass Vector {friend Vector operator(const Vector v1, const Vector v2); // 友元函数重载加法运算符 public:Vector(int x, int y) : x(x), y(y) {}void display() const {std::cout Vector: ( x , y ) std::endl;}private:int x, y; };Vector operator(const Vector v1, const Vector v2) {return Vector(v1.x v2.x, v1.y v2.y); }int main() {Vector v1(1, 2), v2(3, 4);Vector v3 v1 v2;v3.display();return 0; } 练习7.18定义一个Matrix类并将其成员函数transpose声明为友元函数实现矩阵的转置。 示例代码 #include iostreamclass Matrix;class Operations { public:void transpose(Matrix matrix); };class Matrix {friend void Operations::transpose(Matrix matrix); // Operations 的 transpose 函数是 Matrix 的友元 public:Matrix(int rows, int cols) : rows(rows), cols(cols) {data new int*[rows];for (int i 0; i rows; i) {data[i] new int[cols]();}}void setElement(int row, int col, int value) {data[row][col] value;}void display() const {for (int i 0; i rows; i) {for (int j 0; j cols; j) {std::cout data[i][j] ;}std::cout std::endl;}}~Matrix() {for (int i 0; i rows; i) {delete[] data[i];}delete[] data;}private:int **data;int rows, cols; };void Operations::transpose(Matrix matrix) {int **newData new int*[matrix.cols];for (int i 0; i matrix.cols; i) {newData[i] new int[matrix.rows];for (int j 0; j matrix.rows; j) {newData[i][j] matrix.data[j][i];}}for (int i 0; i matrix.rows; i) {delete[] matrix.data[i];}delete[] matrix.data;matrix.data newData;std::swap(matrix.rows, matrix.cols); }int main() {Matrix matrix(2, 3);matrix.setElement(0, 0, 1);matrix.setElement(0, 1, 2);matrix.setElement(0, 2, 3);matrix.setElement(1, 0, 4);matrix.setElement(1, 1, 5);matrix.setElement(1, 2, 6);std::cout Original matrix: std::endl;matrix.display();Operations ops;ops.transpose(matrix);std::cout Transposed matrix: std::endl;matrix.display();return 0; } 总结与提高 本节总结 学习了类成员的高级特性包括初始化列表、成员初始化顺序和常量成员。掌握了返回*this的成员函数的定义和使用理解了链式调用的实现方法。通过友元再探理解了类之间的友元关系、成员函数作为友元、函数重载和友元、友元声明和作用域的概念和应用。 提高建议 多练习初始化列表和成员初始化顺序通过编写各种包含初始化列表和成员初始化顺序的类熟悉这些特性的使用方法。深入理解友元的使用通过实践掌握友元函数和友元类的使用方法理解其在类设计中的作用避免滥用友元导致类的耦合度过高。掌握返回*this的成员函数在编写复杂类时合理使用返回*this的成员函数提高代码的可读性和灵活性。 7.4 类的作用域 7.4.1 类作用域概述 在C中类的成员变量和成员函数有自己的作用域。类作用域决定了这些成员在何处可见以及如何访问。理解类作用域对于正确设计和实现类至关重要。 7.4.2 成员名字的作用域 类的成员名字在类的作用域内是可见的。成员名字包括成员变量、成员函数以及嵌套类型。 示例代码 #include iostreamclass Example { public:void setValue(int value) {this-value value;}void display() const {std::cout Value: value std::endl;}private:int value; };int main() {Example example;example.setValue(42);example.display();return 0; } 在这个示例中value是类Example的成员变量其作用域在整个类内。 7.4.3 类外部定义成员函数 成员函数的定义可以在类的外部进行但仍属于类的作用域。这种方法可以使类的声明更加简洁同时将实现细节分离到类的外部。 示例代码 #include iostreamclass Rectangle { public:Rectangle(double width, double height);double area() const;private:double width;double height; };// 类外部定义成员函数 Rectangle::Rectangle(double width, double height) : width(width), height(height) {}double Rectangle::area() const {return width * height; }int main() {Rectangle rect(5.0, 3.0);std::cout Area: rect.area() std::endl;return 0; } 在这个示例中Rectangle类的构造函数和area函数在类的外部定义。 7.4.4 类的嵌套作用域 嵌套类是定义在另一个类内部的类。嵌套类可以访问其外部类的私有成员而外部类不能直接访问嵌套类的成员。嵌套类有自己的作用域独立于外部类。 示例代码 #include iostreamclass Outer { public:class Inner {public:void display() const {std::cout Inner class std::endl;}};void show() const {std::cout Outer class std::endl;inner.display();}private:Inner inner; };int main() {Outer outer;outer.show();return 0; } 在这个示例中Inner类是Outer类的嵌套类有自己的作用域。 7.4.5 类作用域中的名字查找 名字查找是指在类作用域中查找成员名字的过程。名字查找规则决定了在类中查找成员名字时的顺序和范围。 示例代码 #include iostreamclass Base { public:void display() const {std::cout Base display std::endl;} };class Derived : public Base { public:void display() const {std::cout Derived display std::endl;} };int main() {Derived derived;derived.display(); // 调用的是 Derived 类的 display 函数derived.Base::display(); // 显式调用 Base 类的 display 函数return 0; } 在这个示例中名字查找规则决定了默认调用Derived类的display函数可以通过显式作用域指定调用Base类的display函数。 7.4.6 类的命名空间作用域 类也可以定义在命名空间中这样类及其成员名字的作用域就被限制在命名空间内。命名空间作用域有助于避免名字冲突。 示例代码 #include iostreamnamespace MyNamespace {class MyClass {public:void display() const {std::cout MyNamespace::MyClass std::endl;}}; }int main() {MyNamespace::MyClass obj;obj.display();return 0; } 在这个示例中MyClass类定义在MyNamespace命名空间中其名字作用域被限制在命名空间内。 重点与难点分析 重点 类作用域理解类成员名字的作用域掌握类外部定义成员函数的方法。嵌套类理解嵌套类的作用域和访问规则掌握嵌套类的定义和使用。名字查找规则掌握类作用域中的名字查找规则理解显式作用域指定的用法。命名空间作用域理解类的命名空间作用域掌握在命名空间中定义类的方法。 难点 名字查找规则初学者需要通过实践掌握名字查找规则避免名字冲突和作用域错误。嵌套类的访问规则理解嵌套类与外部类之间的访问规则避免访问权限错误。 练习题解析 练习7.19定义一个Library类包含嵌套类Book并实现展示图书信息的功能。 示例代码 #include iostream #include stringclass Library { public:class Book {public:Book(const std::string title, const std::string author) : title(title), author(author) {}void display() const {std::cout Title: title , Author: author std::endl;}private:std::string title;std::string author;};void addBook(const std::string title, const std::string author) {Book book(title, author);book.display();} };int main() {Library library;library.addBook(1984, George Orwell);return 0; } 练习7.20编写一个Company类包含嵌套类Employee并实现添加和显示员工信息的功能。 示例代码 #include iostream #include string #include vectorclass Company { public:class Employee {public:Employee(const std::string name, int id) : name(name), id(id) {}void display() const {std::cout Employee ID: id , Name: name std::endl;}private:std::string name;int id;};void addEmployee(const std::string name, int id) {employees.emplace_back(name, id);}void showEmployees() const {for (const auto employee : employees) {employee.display();}}private:std::vectorEmployee employees; };int main() {Company company;company.addEmployee(Alice, 101);company.addEmployee(Bob, 102);company.showEmployees();return 0; } 练习7.21定义一个Shape类及其派生类Circle和Rectangle并展示多态性的名字查找规则。 示例代码 #include iostreamclass Shape { public:virtual void draw() const {std::cout Drawing shape std::endl;} };class Circle : public Shape { public:void draw() const override {std::cout Drawing circle std::endl;} };class Rectangle : public Shape { public:void draw() const override {std::cout Drawing rectangle std::endl;} };void drawShape(const Shape shape) {shape.draw(); }int main() {Circle circle;Rectangle rectangle;drawShape(circle); // 调用 Circle::drawdrawShape(rectangle); // 调用 Rectangle::drawreturn 0; } 练习7.22编写一个Zoo类包含嵌套类Animal并实现展示动物信息的功能。 示例代码 #include iostream #include string #include vectorclass Zoo { public:class Animal {public:Animal(const std::string name, const std::string species) : name(name), species(species) {}void display() const {std::cout Name: name , Species: species std::endl;}private:std::string name;std::string species;};void addAnimal(const std::string name, const std::string species) {animals.emplace_back(name, species);}void showAnimals() const {for (const auto animal : animals) {animal.display();}}private:std::vectorAnimal animals; };int main() {Zoo zoo;zoo.addAnimal(Leo, Lion);zoo.addAnimal(Ella, Elephant);zoo.showAnimals();return 0; } 练习7.23定义一个Team类并在命名空间Sports中定义其成员函数实现添加和显示队员信息的功能。 示例代码 #include iostream #include string #include vectornamespace Sports {class Team {public:void addPlayer(const std::string name) {players.push_back(name);}void showPlayers() const {for (const auto player : players) {std::cout Player: player std::endl;}}private:std::vectorstd::string players;}; }int main() {Sports::Team team;team.addPlayer(John);team.addPlayer(Alice);team.showPlayers();return 0; } 总结与提高 本节总结 学习了类作用域的基本概念理解了成员名字的作用域和类外部定义成员函数的方法。掌握了嵌套类的定义和使用理解了嵌套类的作用域和访问规则。理解了类作用域中的名字查找规则掌握了显式作用域指定的用法。理解了类的命名空间作用域掌握了在命名空间中定义类的方法。 提高建议 多练习类作用域和名字查找通过编写各种包含复杂作用域的类熟悉名字查找规则和显式作用域指定的方法。深入理解嵌套类的访问规则通过实践掌握嵌套类与外部类之间的访问规则提高类的设计能力。掌握命名空间作用域在编写大型程序时合理使用命名空间避免名字冲突提高代码的可读性和可维护性。 7.5 构造函数再探 7.5.1 构造函数初始化列表 构造函数初始化列表用于在构造函数体之前初始化类成员。它的优点是能够直接初始化成员而不是在构造函数体内进行赋值从而提高效率。 示例代码 #include iostreamclass Rectangle { public:Rectangle(double width, double height) : width(width), height(height) {} // 初始化列表double area() const {return width * height;}private:double width;double height; };int main() {Rectangle rect(5.0, 3.0);std::cout Area: rect.area() std::endl;return 0; } 在这个示例中Rectangle类的构造函数使用初始化列表直接初始化width和height成员。 7.5.2 默认构造函数 默认构造函数是指不带参数或所有参数都有默认值的构造函数。当我们定义一个类而没有定义任何构造函数时编译器会为我们生成一个默认构造函数。 示例代码 #include iostreamclass Person { public:Person() : name(Unknown), age(0) {} // 默认构造函数void display() const {std::cout Name: name , Age: age std::endl;}private:std::string name;int age; };int main() {Person person;person.display();return 0; } 在这个示例中Person类有一个默认构造函数该构造函数将name初始化为Unknownage初始化为0。 7.5.3 委托构造函数 C11引入了委托构造函数的概念一个构造函数可以调用同一类的另一个构造函数以简化初始化代码。 示例代码 #include iostreamclass Student { public:Student() : Student(Unknown, 0) {} // 委托构造函数Student(const std::string name, int age) : name(name), age(age) {}void display() const {std::cout Name: name , Age: age std::endl;}private:std::string name;int age; };int main() {Student student1;Student student2(Alice, 20);student1.display();student2.display();return 0; } 在这个示例中Student类的默认构造函数委托给另一个带参数的构造函数以简化初始化代码。 7.5.4 拷贝构造函数 拷贝构造函数用于创建一个新对象它是用现有对象的值初始化的。拷贝构造函数的参数是该类对象的引用通常为const引用。 示例代码 #include iostreamclass Box { public:Box(double length, double width, double height) : length(length), width(width), height(height) {}Box(const Box other) : length(other.length), width(other.width), height(other.height) {} // 拷贝构造函数double volume() const {return length * width * height;}private:double length;double width;double height; };int main() {Box box1(10.0, 5.0, 3.0);Box box2 box1; // 使用拷贝构造函数std::cout Box1 volume: box1.volume() std::endl;std::cout Box2 volume: box2.volume() std::endl;return 0; } 在这个示例中Box类的拷贝构造函数通过将另一个Box对象的值赋给当前对象的成员来初始化新对象。 7.5.5 移动构造函数 C11引入了移动构造函数用于高效地转移资源而不是复制。移动构造函数的参数是该类对象的右值引用。 示例代码 #include iostream #include utilityclass Resource { public:Resource() : data(new int[1000]) {}~Resource() { delete[] data; }// 拷贝构造函数Resource(const Resource other) : data(new int[1000]) {std::copy(other.data, other.data 1000, data);}// 移动构造函数Resource(Resource other) noexcept : data(other.data) {other.data nullptr;}private:int *data; };int main() {Resource res1;Resource res2 std::move(res1); // 使用移动构造函数return 0; } 在这个示例中Resource类的移动构造函数通过转移资源所有权避免了不必要的资源复制提高了效率。 7.5.6 隐式的类类型转换 隐式的类类型转换允许我们通过单参数构造函数将其他类型的对象转换为类类型。为了防止这种隐式转换可以在构造函数前加上explicit关键字。 示例代码 #include iostreamclass Complex { public:Complex(double real, double imag) : real(real), imag(imag) {}Complex(double real) : Complex(real, 0.0) {} // 允许从 double 隐式转换为 Complexvoid display() const {std::cout Real: real , Imaginary: imag std::endl;}private:double real;double imag; };int main() {Complex c1 4.5; // 隐式转换c1.display();return 0; } 在这个示例中单参数构造函数允许从double隐式转换为Complex类型。 示例代码使用explicit防止隐式转换 #include iostreamclass Complex { public:explicit Complex(double real, double imag) : real(real), imag(imag) {}explicit Complex(double real) : Complex(real, 0.0) {} // 防止从 double 隐式转换为 Complexvoid display() const {std::cout Real: real , Imaginary: imag std::endl;}private:double real;double imag; };int main() {// Complex c1 4.5; // 编译错误不能隐式转换Complex c2(4.5); // 必须显式转换c2.display();return 0; } 在这个示例中explicit关键字防止了从double到Complex的隐式转换必须显式调用构造函数。 重点与难点分析 重点 构造函数初始化列表掌握构造函数初始化列表的语法和使用方法理解其优点。默认构造函数理解默认构造函数的概念及其生成规则掌握自定义默认构造函数的方法。委托构造函数理解委托构造函数的概念掌握其简化代码的方法。拷贝构造函数理解拷贝构造函数的作用掌握其定义和使用方法。移动构造函数理解移动构造函数的概念掌握其在资源转移中的作用及使用方法。隐式的类类型转换理解隐式类类型转换的概念掌握通过构造函数进行隐式转换的方法以及使用explicit关键字防止隐式转换。 难点 初始化列表与成员初始化顺序初学者需要通过实践掌握初始化列表的使用并注意成员初始化顺序。拷贝构造函数与移动构造函数的区别理解这两者的区别及各自的使用场景避免资源管理问题。隐式转换与显式转换理解隐式转换的风险掌握使用explicit关键字防止不必要的隐式转换。 练习题解析 练习7.24定义一个Book类包含默认构造函数和初始化列表的构造函数并实现展示书籍信息的功能。 示例代码 #include iostream #include stringclass Book { public:Book() : title(Unknown), author(Unknown), pages(0) {} // 默认构造函数Book(const std::string title, const std::string author, int pages) : title(title), author(author), pages(pages) {} // 初始化列表void display() const {std::cout Title: title , Author: author , Pages: pages std::endl;}private:std::string title;std::string author;int pages; };int main() {Book book1;Book book2(C Primer, Lippman, 976);book1.display();book2.display();return 0; } 练习7.25编写一个Movie类包含委托构造函数和默认构造函数实现添加和显示电影信息的功能。 示例代码 #include iostream #include stringclass Movie { public:Movie() : Movie(Unknown, Unknown, 0) {} // 委托构造函数Movie(const std::string title, const std::string director, int duration) : title(title), director(director), duration(duration) {}void display() const {std::cout Title: title , Director: director , Duration: duration minutes std::endl;}private:std::string title;std::string director;int duration; };int main() {Movie movie1;Movie movie2(Inception, Christopher Nolan, 148);movie1.display();movie2.display();return 0; } 练习7.26定义一个Vector类包含拷贝构造函数和移动构造函数并实现向量的初始化和展示功能。 示例代码 #include iostreamclass Vector { public:Vector(size_t size) : size(size), data(new int[size]) {std::fill(data, data size, 0);}~Vector() { delete[] data; }// 拷贝构造函数Vector(const Vector other) : size(other.size), data(new int[other.size]) {std::copy(other.data, other.data other.size, data);}// 移动构造函数Vector(Vector other) noexcept : size(other.size), data(other.data) {other.size 0;other.data nullptr;}void display() const {for (size_t i 0; i size; i) {std::cout data[i] ;}std::cout std::endl;}private:size_t size;int *data; };int main() {Vector vec1(5);Vector vec2 vec1; // 拷贝构造函数Vector vec3 std::move(vec1); // 移动构造函数vec2.display();vec3.display();return 0; } 练习7.27编写一个Game类包含委托构造函数和拷贝构造函数实现游戏信息的添加和展示功能。 示例代码 #include iostream #include stringclass Game { public:Game() : Game(Unknown, Unknown, 0) {} // 委托构造函数Game(const std::string title, const std::string developer, int rating) : title(title), developer(developer), rating(rating) {}// 拷贝构造函数Game(const Game other) : title(other.title), developer(other.developer), rating(other.rating) {}void display() const {std::cout Title: title , Developer: developer , Rating: rating /10 std::endl;}private:std::string title;std::string developer;int rating; };int main() {Game game1(The Witcher 3, CD Projekt, 10);Game game2 game1; // 使用拷贝构造函数game1.display();game2.display();return 0; } 练习7.28定义一个Currency类包含隐式的类类型转换并实现从double类型到Currency类型的隐式转换。 示例代码 #include iostreamclass Currency { public:Currency(double amount) : amount(amount) {} // 隐式转换构造函数void display() const {std::cout Amount: $ amount std::endl;}private:double amount; };int main() {Currency money 100.50; // 隐式转换money.display();return 0; } 练习7.29使用explicit关键字防止隐式转换并展示从double类型到Currency类型的显式转换。 示例代码 #include iostreamclass Currency { public:explicit Currency(double amount) : amount(amount) {} // 防止隐式转换void display() const {std::cout Amount: $ amount std::endl;}private:double amount; };int main() {// Currency money 100.50; // 编译错误不能隐式转换Currency money(100.50); // 必须显式转换money.display();return 0; } 总结与提高 本节总结 学习了构造函数初始化列表的概念及其应用掌握了如何通过初始化列表直接初始化成员变量。掌握了默认构造函数和委托构造函数的使用方法理解了其简化代码的优势。理解了拷贝构造函数和移动构造函数的作用掌握了它们的定义和使用方法。学习了隐式的类类型转换的概念掌握了通过构造函数进行隐式转换的方法以及使用explicit关键字防止隐式转换的方法。 提高建议 多练习构造函数的使用通过编写各种包含默认构造函数、初始化列表、委托构造函数、拷贝构造函数和移动构造函数的类熟悉这些特性的使用方法。深入理解拷贝和移动语义通过实践掌握拷贝构造函数和移动构造函数的区别及各自的使用场景避免资源管理问题。合理设计构造函数在编写类时合理设计构造函数确保对象初始化的正确性和效率。掌握隐式转换与显式转换通过实践理解隐式转换的风险掌握使用explicit关键字防止不必要的隐式转换的方法。 7.6 类的静态成员 7.6.1 静态数据成员 静态数据成员是属于类的而不是属于某个具体对象的成员。所有对象共享同一个静态数据成员它在类的所有对象之间共享。静态数据成员必须在类的外部进行定义和初始化。 示例代码 #include iostreamclass Account { public:void deposit(double amount) {balance amount;totalDeposits amount;}double getBalance() const {return balance;}static double getTotalDeposits() {return totalDeposits;}private:double balance 0.0;static double totalDeposits; };double Account::totalDeposits 0.0;int main() {Account acc1, acc2;acc1.deposit(100);acc2.deposit(200);std::cout Account 1 Balance: acc1.getBalance() std::endl;std::cout Account 2 Balance: acc2.getBalance() std::endl;std::cout Total Deposits: Account::getTotalDeposits() std::endl;return 0; } 在这个示例中totalDeposits是一个静态数据成员在所有Account对象之间共享。 7.6.2 静态成员函数 静态成员函数不属于某个具体的对象而是属于类的。静态成员函数只能访问静态数据成员和其他静态成员函数不能访问非静态数据成员或非静态成员函数。 示例代码 #include iostreamclass Example { public:static void setValue(int val) {value val;}static int getValue() {return value;}private:static int value; };int Example::value 0;int main() {Example::setValue(42);std::cout Value: Example::getValue() std::endl;return 0; } 在这个示例中value是一个静态数据成员setValue和getValue是静态成员函数它们用于访问和修改静态数据成员。 7.6.3 静态成员的初始化 静态数据成员通常必须在类的外部进行初始化但在某些情况下特别是对于const整型和枚举类型的静态数据成员可以在类内直接进行初始化。 示例代码 #include iostreamclass Counter { public:Counter() {count;}static int getCount() {return count;}private:static int count;static const int limit 100; // 类内初始化 };int Counter::count 0;int main() {Counter c1, c2, c3;std::cout Number of objects created: Counter::getCount() std::endl;std::cout Limit: Counter::limit std::endl;return 0; } 在这个示例中count是一个静态数据成员在类的外部进行初始化而limit是一个const整型静态数据成员可以在类内直接进行初始化。 对于非const整型或非枚举类型的静态数据成员仍然需要在类的外部进行初始化。 7.6.4 静态成员的使用场景 静态成员常用于需要在多个对象之间共享数据或在没有对象的情况下调用的功能。例如 计数器用于统计类的对象创建的数量。配置参数用于存储在多个对象之间共享的配置信息。工厂方法用于创建和管理类的实例。 示例代码工厂方法 #include iostream #include vectorclass Singleton { public:static Singleton* getInstance() {if (!instance) {instance new Singleton();}return instance;}void display() const {std::cout Singleton instance std::endl;}private:Singleton() default;static Singleton* instance; };Singleton* Singleton::instance nullptr;int main() {Singleton* s1 Singleton::getInstance();Singleton* s2 Singleton::getInstance();s1-display();s2-display();std::cout s1 and s2 are (s1 s2 ? the same : different) instances. std::endl;return 0; } 在这个示例中Singleton类使用静态数据成员和静态成员函数实现了单例模式确保类的唯一实例。 重点与难点分析 重点 静态数据成员理解静态数据成员的概念和用途掌握静态数据成员的定义和初始化方法。静态成员函数掌握静态成员函数的定义和使用方法理解静态成员函数的限制。静态成员的初始化理解静态数据成员必须在类的外部初始化的要求。 难点 静态成员的作用域和生命周期初学者需要理解静态成员的作用域和生命周期掌握静态成员在不同对象之间共享数据的特性。静态成员函数的限制静态成员函数不能访问非静态成员需要掌握如何在静态成员函数中进行适当的设计和实现。 练习题解析 练习7.30定义一个Library类包含静态数据成员totalBooks并实现统计图书数量的功能。 示例代码 #include iostreamclass Library { public:Library() {totalBooks;}static int getTotalBooks() {return totalBooks;}private:static int totalBooks; };int Library::totalBooks 0;int main() {Library lib1, lib2, lib3;std::cout Total books: Library::getTotalBooks() std::endl;return 0; } 练习7.31编写一个Database类包含静态成员函数connect用于模拟数据库连接。 示例代码 #include iostreamclass Database { public:static void connect() {std::cout Connecting to database... std::endl;connections;}static int getConnections() {return connections;}private:static int connections; };int Database::connections 0;int main() {Database::connect();Database::connect();std::cout Total connections: Database::getConnections() std::endl;return 0; } 练习7.32定义一个Student类包含静态数据成员totalStudents和静态成员函数getTotalStudents并实现统计学生数量的功能。 示例代码 #include iostream #include stringclass Student { public:Student(const std::string name) : name(name) {totalStudents;}static int getTotalStudents() {return totalStudents;}private:std::string name;static int totalStudents; };int Student::totalStudents 0;int main() {Student s1(Alice), s2(Bob), s3(Charlie);std::cout Total students: Student::getTotalStudents() std::endl;return 0; } 练习7.33编写一个Logger类包含静态数据成员logCount和静态成员函数log用于记录日志信息。 示例代码 #include iostream #include stringclass Logger { public:static void log(const std::string message) {logCount;std::cout Log # logCount : message std::endl;}static int getLogCount() {return logCount;}private:static int logCount; };int Logger::logCount 0;int main() {Logger::log(Starting the application);Logger::log(Performing an operation);Logger::log(Shutting down the application);std::cout Total log entries: Logger::getLogCount() std::endl;return 0; } 练习7.34定义一个Configuration类包含静态数据成员settings和静态成员函数getSetting用于存储和访问配置参数。 示例代码 #include iostream #include unordered_map #include stringclass Configuration { public:static void setSetting(const std::string key, const std::string value) {settings[key] value;}static std::string getSetting(const std::string key) {return settings[key];}private:static std::unordered_mapstd::string, std::string settings; };std::unordered_mapstd::string, std::string Configuration::settings;int main() {Configuration::setSetting(language, C);Configuration::setSetting(version, C11);std::cout Language: Configuration::getSetting(language) std::endl;std::cout Version: Configuration::getSetting(version) std::endl;return 0; } 总结与提高 本节总结 学习了静态数据成员和静态成员函数的定义和使用方法理解了它们在类中的作用和特性。掌握了静态成员的初始化方法理解了静态数据成员必须在类的外部进行初始化的要求。通过示例代码和练习题理解了静态成员在实际编程中的应用场景和设计方法。 提高建议 多练习静态成员的定义与使用通过编写各种包含静态成员的类熟悉静态成员的初始化和调用方法掌握其在不同对象之间共享数据的特性。深入理解静态成员函数的限制通过实践掌握静态成员函数不能访问非静态成员的限制理解在静态成员函数中进行设计和实现的方法。合理设计静态成员在编写类时合理设计静态成员确保数据和功能在多个对象之间的共享和管理提高代码的可维护性和可扩展性。 本主页会定期更新为了能够及时获得更新敬请关注我点击左下角的关注。也可以关注公众号请在微信上搜索公众号“iShare爱分享”并关注或者扫描以下公众号二维码关注以便在内容更新时直接向您推送。
http://www.w-s-a.com/news/651726/

相关文章:

  • 响应式网站开发流程图网站优化seo教程
  • 做汽车团购网站百度官网平台
  • 网站增加关键字建设旅游网站的功能定位
  • 怎么搭建源码网站义乌网络
  • 定远规划建设局网站wordpress云主机安装
  • 慈溪市网站开发软件开发文档国家标准
  • 本地佛山顺德网站设计公司的网站如何建设
  • 网站建设前十名网站建设 招标书
  • 手机网站标准百度搜索关键词排名优化推广
  • 中国空间站科幻作文1000字wordpress运行库
  • 徐州做网站的wordpress可视化编辑器排行
  • 官方网站英语上海公司注册核名查询
  • 东莞网站建设推广云南昆明最新消息
  • 上网站乱码网页设计与网站建设案例教程
  • 宣讲网站建设wordpress多媒体主题
  • 如何成立网站互联网开发是做什么的
  • 网站首页的尺寸做多大网页图片排版
  • 龙岩天宫山索道多少钱河南网站排名优化哪家好
  • 北京做网站设计程序员和网站开发
  • 个人 做自媒体 建网站图片制作成视频的手机软件
  • h5 建站网站 移动端重庆潼南网站建设价格
  • 商企在线营销型网站怎么做时光网站
  • 网站建设方案论文1500竞价托管哪家便宜
  • 使用cdn的网站宣武网站建设
  • 营销型网站怎么建设企业网站Wap在线生成
  • 网站建设服务费应该做到什么科目广州网页制作服务商
  • 网站显示500错误怎么解决方法店面设计模板
  • 网站备案icp文化传媒有限公司
  • 北京企业建站模板微信公众号商城怎么制作
  • 制作网站 公司简介大型做网站的公司