赞
踩
C++中的结构体是一种用户自定义的数据类型,它可以用来存储一组具有不同数据类型的数据。结构体可以被用来描述一个实体,如学生、联系人等。
结构体的基本语法如下:
struct struct_name {
data_type member1;
data_type member2;
// ...
};
struct Student {
string name;
int age;
int id;
};
结构体变量可以通过使用结构体类型名和点运算符来访问结构体成员。
例如:
Student s1;
s1.name = "John Doe";
s1.age = 21;
s1.id = 6;
// C语言的结构体 struct Student{ char* name; int age; float score; }; void struct_demo() { // 定义一个student1 Student s1; s1.name = "cqy"; s1.age = 18; s1.score = 100; // Student 2 Student s2; s2.name = "cxk"; s2.age = 200; std::cout << "Student 1 name " << s1.name << " age: "<< s1.age << std::endl; std::cout << "Student 2 name " << s2.name << " age: "<< s2.age << std::endl; }
class 类名
{
访问控制符:
成员变量 //属性;
成员函数 //方法
};
// C++ 类 class Student{ public: char* name; int age; float score; }; void class_demo() { // 定义一个student1 Student s1; s1.name = "cqy"; s1.age = 18; s1.score = 100; // Student 2 Student s2; s2.name = "cxk"; s2.age = 200; std::cout << "Student 1 name " << s1.name << " age: "<< s1.age << std::endl; std::cout << "Student 2 name " << s2.name << " age: "<< s2.age << std::endl; }
// C++ 类 class Student{ public: // 两个激活函数 int get_age() { return age_; } void setAge(int age) {age_ = age; } void say(); private: int age_; float score_; }; void Student::say() { std::cout << "cqy age is: " << age_ << std::endl; } void class_demo() { // 定义一个student1 Student s1; // 实例化一个类对象 s1.setAge(20); std::cout << "Student 1 Age: " << s1.get_age() << std::endl; s1.say(); }
Student 1 Age: 20
cqy age is: 20
// C++ 类
class Student{
public:
// 两个激活函数
int get_age() { return age_; }
void setAge(int age) {age_ = age; }
void say();
private:
int age_;
float score_;
};
#include <iostream>
#include "class_demo.h"
void Student::say() {
std::cout << "cqy age is: " << age_ << std::endl;
}
int main() {
// 定义一个student1
Student s1; // 实例化一个类对象
s1.setAge(20);
std::cout << "Student 1 Age: " << s1.get_age() << std::endl;
s1.say();
return 0;
}
// #pragma once #ifndef CLASS_FIRST_ #define CLASS_FIRST_ namespace Demo{ // C++ 类 class Student{ public: // 两个激活函数 int get_age() { return age_; } void setAge(int age) {age_ = age; } void say(); private: int age_; float score_; }; } // namespace class_demo #endif
#include <iostream> #include "class_demo.h" namespace Demo{ void Student::say() { std::cout << "cqy age is: " << age_ << std::endl; } } int main() { // 定义一个student1 Demo::Student s1; // 实例化一个类对象 s1.setAge(20); std::cout << "Student 1 Age: " << s1.get_age() << std::endl; s1.say(); return 0; }
#include <iostream> class Person { public: // constructor with two parameters Person(std::string name = "default", int age = 0) : name_(name), age_(age) {} // member variables std::string name_; int age_; }; int main() { Person p1("asd", 10); Person p2; std::cout << "P1 name is: " << p1.name_ << std::endl; std::cout << "P2 name is: " << p2.name_ << std::endl; return 0; }
python里面有一个init构造函数,C++里面也是有的
实例化的有构造函数构造出实例化对象
如果你在类中定义了构造函数,那么编译器不再会自动生成默认构造函数。如果你还想使用默认构造函数,你需要自己显式地添加一个默认构造函数。
如果你在实例化类的时候不传递任何参数,那么如果类中没有默认构造函数,那么将会报错,因为编译器无法找到可用的构造函数。
如果你在类中定义了一个默认构造函数,那么在实例化类的时候不传递任何参数,那么将会调用你自己定义的默认构造函数。
如果你使用 C++11 以上版本,可以使用关键字 default 来显式地保留默认构造函数
下面也展示了两种初始化的方法
下面为*.h文件
// #pragma once #ifndef CLASS_FIRST_ #define CLASS_FIRST_ namespace Demo{ class Student{ public: // 保留构造函数 Student() = default; // 构造函数的声明 Student(const char* name , int age, float score); public: // 两个激活函数 int get_age() { return age_; } void setAge(int age) {age_ = age; } void say(); void setName(char* name) {name_ = name;} private: // 在定义的时候给成员变量赋予默认值 const char* name_ = nullptr; int age_ = 0; float score_ = 0; }; } // namespace class_demo #endif
#include <iostream> #include "class_demo.h" namespace Demo{ // 类的初始化 Student::Student(const char* name, int age, float score): name_(name), age_(age),score_(score) { std::cout << "==============start Construct===============" << std::endl; // 与上面同等写法 // name_ = name; // age_ = age; // score_ = score; std::cout << "================end Construct===============" << std::endl; } void Student::say() { std::cout << "cqy age is: " << age_ << std::endl; } } int main() { // 定义一个student1 Demo::Student s1("cqy", 20, 100); // 实例化一个类对象, 这里调用我们定义的构造函数 Demo::Student s2; // 这里调用默认构造函数 s1.setAge(20); std::cout << "Student 1 Age: " << s1.get_age() << std::endl; s1.say(); return 0; }
#include <iostream> class Shape { public: // 保留默认构造函数 Shape() = default; // 自己定义一个构造函数初始化, C++ 11语法 Shape(int width, int height): width_(width), height_(height) {} // 当函数是 const 时,表示它不会改变对象的状态。这是一种好的编程习惯, // 因为它可以防止意外修改对象的状态 int GetWidth() const {return width_;} int GetHeight() const {return height_;} // 改变对象状态的函数 // 改变对象状态,就是通过函数来修改对象的成员变量的值 void setWidth(int width) {width_ = width;} void setHeight(int height) {height_ = height;} int GetArea() const {return width_ * height_;} private: // 定义初始化参数,不写的话自动给0 int width_ = 10; int height_ = 5; }; int main() { // 初始化一个shape Shape shape; std::cout << "默认初始化的width: " << shape.GetWidth() << std::endl; std::cout << "默认初始化的Height: " << shape.GetHeight() << std::endl; std::cout << "默认初始化的Area: " << shape.GetArea() << std::endl; return 0; }
在 C++ 中,this 是一个特殊的指针,它指向当前对象。当我们在类的函数中使用 this-> 时,它会指向调用该函数的对象。
比如说,在下面的代码中:
class Shape {
public:
Shape() = default;
Shape(int width, int height) : width_(width), height_(height) {}
int GetWidth() const { return width_; }
void SetWidth(int width) { width_ = width; }
void SetWidthThroughThis(int width) { this->width_ = width; }
private:
int width_;
};
Shape shape;
shape.SetWidth(5);
这个函数就会把shape对象的 width_ 成员变量赋值为 5。
而如果我们调用 SetWidthThroughThis(int width) 函数,就会像这样
shape.SetWidthThroughThis(5);
使用 this-> 是一种好的编程习惯,它可以在代码中清晰地表示出当前访问的是对象的成员变量,而不是局部变量。这样可以避免命名冲突,提高代码的可读性。
另外,在某些情况下,使用 this-> 可以解决默认参数和局部变量之间的命名冲突。
总之,使用 this-> 是一种可以提高代码可读性和健壮性的好的编程习惯。
静态变量和静态函数都是类的成员,它们与类本身有关,而不是与对象有关。
本身跟类的互动不频繁
静态变量是类的全局变量,它只有一个实例,不管类有多少个对象,它们共享同一个静态变量。 通过类名::来访问。
在这个例子中,我们定义了一个静态变量 total_shapes_ 和两个静态函数 GetTotalShapes() 和 IncreaseTotalShapes()。
静态变量 total_shapes_ 不属于任何一个对象,所有对象共享它。
静态函数 GetTotalShapes() 返回静态变量 total_shapes_ 的值, IncreaseTotalShapes() 函数增加 total_shapes_ 的值。
#include <iostream> class Shape { public: Shape() = default; Shape(int width, int height) : width_(width), height_(height) {} int GetWidth() const { return width_; } void SetWidth(int width) { width_ = width; } // 静态变量 static int GetTotalShapes() { return total_shapes_; } // 静态函数 static void IncreaseTotalShapes() { total_shapes_++; } private: int width_; int height_; // 静态变量 static int total_shapes_; }; int Shape::total_shapes_ = 0; int main() { Shape shape1(3, 4); Shape shape2(5, 6); std::cout << "Total Shapes: " << Shape::GetTotalShapes() << std::endl; Shape::IncreaseTotalShapes(); Shape::IncreaseTotalShapes(); std::cout << "Total Shapes: " << Shape::GetTotalShapes() << std::endl; return 0; }
在 C++ 中,友元函数是一种特殊的函数,它可以访问类的私有成员变量和私有成员函数。这是因为类的私有成员变量和私有成员函数是只能被类的成员函数访问的,而友元函数不属于类的成员函数。
友元函数通过在类中用关键字 friend 声明来实现。
友元类改的是class的状态,不是实例化出来的object的状态
友元类/函数使用的时都要传入实例化的object
这是一个友元函数的案例:
class MyClass {
friend void MyFriendFunction(MyClass& my_class);
private:
int x_;
};
void MyFriendFunction(MyClass& my_class) {
my_class.x_ = 5; // 访问类的私有成员变量
}
在这个例子中,MyFriendFunction 是一个友元函数,它可以访问 MyClass 类的私有成员变量 x_ 。因为在 MyClass 类中使用了 friend 关键字来声明 MyFriendFunction 是友元函数。
另外,友元函数可以是一个类的成员函数,也可以是一个全局函数。
需要注意的是,友元函数并不属于类的成员函数,它不能访问类的 this 指针。
完整的一个大代码
#include <iostream> using namespace std; class Box { public: // 声明友元函数 friend void printWidth(Box& box); // 声明友元类 friend class BigBox; // 保留默认构造函数 Box() = default; // 自定义构造函数 Box(int width): width_(width) {} void setWidth(float width) {width_ = width;} int getWidth() {return width_;} private: float width_ = 5; }; class BigBox{ public: // 写一个函数更改变量 void print(int width, Box& box) { box.setWidth(width); cout << "width of box: " << box.width_ << endl; } }; void Box_test() { Box box; cout << "默认的width: " << box.getWidth() << endl; box.setWidth(6); cout << "更改后的width: " << box.getWidth() << endl; } void BigBox_test() { Box box; BigBox bigbox; box.setWidth(9.0); bigbox.print(20, box); // 这里就把Box的width_改了,不是改实例化出来的box cout << "box width after friend class change: " << box.getWidth() <<endl; } void printWidth(Box& box) { cout << "friend box width_ is: " << box.width_ << endl; } int main() { // Box_test(); // BigBox_test(); Box box; printWidth(box); return 0; }
#include <iostream> class Shape{ public: // 保留默认构造函数 Shape() = default; Shape(int width, int height): width_(width), height_(height) {} // 成员函数 public: void setWidth(int width) {width_ = width;} void setHeight(int height) {height_ = height;} // 成员变量 protected: int width_ = 5; int height_ = 5; }; class Rectangle: public Shape { public: // 成员函数 int getArea() { // 继承的class Shape 的width_, height_ return width_ * height_; } }; int main() { Rectangle rect; // 继承了Shape就可以用他的成员函数 rect.setHeight(10); rect.setWidth(10); std::cout << "Area: " << rect.getArea() << std::endl; return 0; }
#include <iostream> class Shape{ public: // 保留默认构造函数 Shape() = default; Shape(int width, int height): width_(width), height_(height) {} // 成员函数 public: void setWidth(int width) {width_ = width;} void setHeight(int height) {height_ = height;} // 成员变量 protected: int width_ = 5; int height_ = 5; }; class Cost { public: auto getCost(int area) {return area * 70;} }; class Rectangle: public Shape, public Cost { public: // 成员函数 int getArea() { // 继承的class Shape 的width_, height_ return width_ * height_; } }; int main() { Rectangle rect; // 继承了Shape就可以用他的成员函数 rect.setHeight(10); rect.setWidth(10); std::cout << "Area: " << rect.getArea() << std::endl; auto area = rect.getArea(); auto cost = rect.getCost(area); std::cout << "Cost of rect is: " << cost << std::endl; return 0; }
// A // / \ // B C // \ / // D #include <iostream> using namespace std; class A{ public: void func() { std::cout << "Class A" << std::endl; } protected: int base_; }; class B: public A{ public: protected: int b_; }; class C: public A{ public: protected: int c_; }; class D: public B, public C{ public: protected: int d_; }; int main() { // 实例化b B b; b.func(); // 实例化d D d; d.func(); // 不可以访问了 return 0; }
B可以访问,但是D不能访问
因为func() 是来自于A的,B,C都继承自A,编译器就不知道该从哪条线来访问func(); 就会报错
第二种解决办法: 指明怎么访问的就行了把 d.func(); 改成
d.B::func();
#include <iostream> class Shape{ public: // 保留默认构造函数 Shape() = default; Shape(int width, int height): width_(width), height_(height) {} // 成员函数 public: void setWidth(int width) {width_ = width;} void setHeight(int height) {height_ = height;} // 成员变量 protected: int width_ = 5; int height_ = 5; }; class Cost { public: auto getCost(int area) {return area * 70;} }; class Rectangle: public Shape, public Cost { public: // 成员函数 int getArea() { // 继承的class Shape 的width_, height_ return width_ * height_; } int getShapeArea() { return Shape::height_ * Shape::width_; } private: int width_ =100; // 嵌套变量的作用域: int height_ = 700; }; int main() { Rectangle rect; // 继承了Shape就可以用他的成员函数 rect.setHeight(10); rect.setWidth(10); std::cout << "Area: " << rect.getArea() << std::endl; auto area = rect.getArea(); auto area2 = rect.getShapeArea(); auto cost = rect.getCost(area); auto cost2 = rect.getCost(area2); std::cout << "Cost1 of rect is: " << cost << std::endl; std::cout << "Cost2 of rect is: " << cost2 << std::endl; std::cout << "Cost2 of rect is: " << sizeof(Shape) << std::endl; return 0; }
auto getCost(int area) {return area * 70;}
void getCost() {
std::cout << "We are in getCost func in calss rect " << std::endl;
}
void getCost(int area) {std::cout << "area is " << area << std::endl;}
void getCost() {
std::cout << "We are in getCost func in calss rect " << std::endl;
}
void func(){}
void func(int x){}
void func(char x){}
void func(int x, int y){}
void func(int x, char y){}
void func(char y, int x){}
#include <iostream> using namespace std; // 基类/父类 class A { protected: int z; private: int x; public: A() // 默认构造函数 { cout << "A()" << endl; } ~A() { cout << "~A()" << endl; } // 自定义构造函数 A(int a, int b) : z(a), x(b) { cout << "A(int a, int b)" << endl; } int get_z() { return z; } int get_x() { return x; } void set_x(int x) { this->x = x; } }; // 派生类/子类 class B : public A { public: B() { cout << "B()" << endl; } ~B() { cout << "~B()" << endl; } // 指定使用父类的构造函数 // A中有默认构造函数和带参数的构造函数 B(int a, int b) : A(a, b) { cout << "B(int a, int b)" << endl; } }; int main() { // B b; // 先调用基类的构造函数再调用自己的构造函数 cout << "------------------------" << endl; B b1(10, 20); // 这里的参数是显示调用A类的自定义构造函数 return 0; // 这里调用析构函数,先调用派生类的析构函数再调用基类的构造函数 }
class A { public: int x; protected: int y; private: int z; public: A(){cout << "基类的构造函数" << endl;} ~A(){cout << "基类的析构函数" << endl;} }; class E:public A { public: int x; E(){cout << "派生类的构造函数" << endl;}; ~E(){cout << "派生类的析构函数" << endl;}; }; int main() { E e; cout << "sizeof(E): " << sizeof(E) << endl; //16 return 0; }
class A { public: int x; public: A() { this->x = 1; cout << "基类的构造函数" << endl; } A(int x) { this->x = x; cout << "基类中的A(int x)构造函数" << endl; } void func_a() { cout << "func_a" << endl; } }; class E : public A { public: int x; E() { cout << "派生类的默认构造函数" << endl; } E(int a) : x(a) { cout << "派生类中的构造函数E(int a)" << endl; } ~E() { cout << "派生类中的析构函数" << endl; } }; int main() { E e(10); // 如果子类有成员和父类同名,子类访问其成员默认访问子类的成员(本作用域,就近原则) cout << e.x << endl; // 当子类成员和父类成员同名时,子类依然从父类继承同名成员 // 在子类通过作用域::进行同名成员区分(在派生类中使用基类的同名成员,显示使用类名限定符) cout << e.A::x << endl; cout << sizeof(E) << endl; // 两个int,所以是8 }
// 1. func2() 父类子类名称相同,参数不相同,父类的方法被隐藏 // 2. func1() 父类子类名称相同,参数也相同,但是没有virtual,父类的方法被隐藏 class Father { public: void func1() {cout << "father func1" << endl;} void func2(int x) {cout << "father func2" << endl;} }; class Son : public Father { public: void func1() {cout << "son func1" << endl;} void func2(char x) {cout << "son func2" << endl;} }; int main() { Father father; Son son; son.func1(); son.func2('s'); return 0; }
class Base { public: static int getNum() { return sNum; } static int getNum(int param){ return sNum + param; } public: static int sNum; }; int Base ::sNum = 10; class Derived : public Base { public: static int sNum; // 这里的话父类同名的成员属性被隐藏 // 父类的方法同样被隐藏了 // 改变基类中一个函数的特征,所有使用该函数名的基类版本都会被隐藏 static int getNum(int param1, int param2) { return sNum + param1 + param2; } }; int Derived :: sNum = 100; int main() { Base obj; cout << obj.getNum() << endl; cout << obj.getNum(1) << endl; Derived obj2; // 编译器报错,这里不会去父类找可以匹配到的,因为被隐藏了 // obj2.getNum(); cout << obj2.getNum(1, 2) << endl; return 0; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。