QT实操中 遇到的一些C++疑惑点汇总
1.实例化对象的两种方法及其访问方式
1.1 示例
1.2 总结2.基类成员的访问
2.1 直接访问继承的基类成员
2.1.1示例代码
2.1.2 输出结果2.2 使用作用域解析符来显式调用基类成员函数
2.2.1 示例代码
2.2.2 输出结果2.3 使用 this 指针访问基类成员
2.3.1 示例代码
2.3.2 输出结果2.4 总结
3.枚举 与 运算符 :: 的使用
3.1 困惑的引入
3.2 C++枚举的总结
3.2.1 枚举的走义
3.2.2 枚举的使用
1>声明
2>条件语句中使用
3.2.3 使用枚举的例子(类名::枚举成员)
3.2.3 枚举的范围和作用域
3.2.4 强枚举的优点3.3 运算符::的使用
3.3.1 静态成员
3.3.2 命名空间成员
3.3.3 枚举或常量
3.3.4 基类成员
3.3.5 总结
1. 实例化对象的两种方法及其访问方式
在C++中,如果对象是通过new
关键字创建的,那它的类型就是指针,需要使用->
来访问其成员。而如果对象是直接实例化的(不使用new
),那它是一个具体的对象实例,用.
来访问成员。
1.1 示例
-
使用
new
创建对象指针:QRadioButton* radioButton = new QRadioButton(this); // 创建一个指针指向 QRadioButton 对象 radioButton->setText("开关一"); // 使用 "->" 来访问成员
-
直接实例化对象:
QRadioButton radioButton; // 创建一个 QRadioButton 的实例对象 radioButton.setText("开关一"); // 使用 "." 来访问成员
1.2 总结
- 使用
new
:对象是指针类型,成员访问使用->
。 - 直接实例化:对象是值类型(直接实例),成员访问使用
.
。
->
和.
的选择取决于对象是指针还是实例化的具体对象。
2. 基类成员的访问
-
在 C++ 中,如果你有一个派生类的对象,并希望引用该对象的基类成员(包括变量或函数),可以通过直接访问或显式调用基类作用域的方式实现。
-
本质都是通过
::
,注意区别于继承的操作符,继承使用:
,以下是一些常见方法:- 直接访问:如果基类成员是
public
或protected
,可直接通过::
访问。 - 作用域解析符:通过
Base::成员名
形式访问同名基类成员。 this
指针:使用this->Base::成员名
可以更显式地标明访问基类成员。
- 直接访问:如果基类成员是
2.1 直接访问继承的基类成员
如果基类成员是public
或protected
,并且派生类是通过public
或protected
继承基类,可以直接在派生类的对象中访问这些成员。
2.1.1 示例代码
#include <iostream>
#include <string>class Base {
public:int baseVar; // 基类的变量成员Base(int val) : baseVar(val) {} // 基类构造函数初始化成员变量void showBaseVar() const {std::cout << "基类成员 baseVar: " << baseVar << std::endl;}
};class Derived : public Base {
public:int derivedVar;Derived(int baseVal, int derivedVal) : Base(baseVal), derivedVar(derivedVal) {}void showValues() {// 直接访问基类成员变量std::cout << "基类成员 baseVar: " << baseVar << std::endl;// 直接调用基类成员函数showBaseVar();// 使用派生类成员变量std::cout << "派生类成员 derivedVar: " << derivedVar << std::endl;}
};int main() {Derived derivedObj(10, 20); // 创建派生类对象derivedObj.showValues(); // 输出基类和派生类成员return 0;
}
2.1.2 输出结果
基类成员 baseVar: 10
基类成员 baseVar: 10
派生类成员 derivedVar: 20
在 showValues
方法中,我们直接使用 baseVar
和 showBaseVar()
来访问基类的成员变量和函数。
2.2 使用作用域解析符来显式调用基类成员函数
当派生类有与基类同名的成员函数或变量时,可以使用作用域解析符(::
)来访问基类的成员,以避免名称冲突。
2.2.1 示例代码
#include <iostream>class Base {
public:void display() {std::cout << "Base 类的 display() 函数" << std::endl;}
};class Derived : public Base {
public:void display() {std::cout << "Derived 类的 display() 函数" << std::endl;}void show() {// 调用派生类的 display() 函数display();// 调用基类的 display() 函数Base::display();}
};int main() {Derived derivedObj;derivedObj.show();return 0;
}
2.2.2 输出结果
Derived 类的 display() 函数
Base 类的 display() 函数
在 Derived::show
中,通过 Base::display()
显式调用基类的 display()
函数。
2.3 使用 this
指针访问基类成员
当基类成员与派生类成员同名时,可以用this
指针加上作用域解析符来明确访问基类成员。
2.3.1 示例代码
#include <iostream>class Base {
public:int var = 5;
};class Derived : public Base {
public:int var = 10;void show() {std::cout << "派生类 var: " << var << std::endl; // 访问派生类的 varstd::cout << "基类 var: " << this->Base::var << std::endl; // 显式访问基类的 var}
};int main() {Derived derivedObj;derivedObj.show();return 0;
}
2.3.2 输出结果
派生类 var: 10
基类 var: 5
2.4 总结
- 直接访问:如果基类成员是
public
或protected
,可直接访问。 - 作用域解析符:通过
Base::成员名
形式访问同名基类成员。 this
指针:使用this->Base::成员名
可以更显式地标明访问基类成员。
3. 枚举 与 运算符::
的使用
3.1 困惑的引入
上代码片段:
/* 判断文件是否存在 */if (file.exists() ){/* 以只读的方式打开 */file.open(QFile::ReadOnly); // 参数为QFile的枚举值ReadOnly/* 以字符串的方式保存读出的结果 */QString styleSheet = QLatin1String(file.readAll());/* 设置全局样式 */qApp->setStyleSheet(styleSheet);/* 关闭文件 */file.close();}
一个类中定义了枚举成员,类的实例化对象可通过 类名::枚举成员
的方式来引用该枚举值。
ps:我还以为有点钻牛角尖了,巨困惑QFile::ReadOnly到底是个啥?1> 开始还理解成继承,一想这个作为一个参数,怎么可能是一个类;2> 后面想着肯定是参数,又知道::是引用成员变量,那么类咋还能直接一个常量?( 查了ReadOnly是一个八进制数进行的替换 )3> 然后就查了C++枚举,后觉得没理解错啊,一查,还真”**一个类中定义了枚举成员,类的实例化对象可以通过 `类名::枚举成员` 的方式来引用该枚举值**。“!
因此,特来进行C++枚举的总结,和**::
运算符的使用**!
3.2 C++枚举的总结
枚举(enum
)在 C++ 中是一种用户自定义的数据类型,用于定义一组具名的整型常量。它可以使代码更易读、易维护,并能提供更强的类型安全性。以下是枚举的定义与使用的详细讲解:
3.2.1 枚举的定义
枚举可以通过 enum
关键字进行定义。基本的枚举定义如下:
enum Color {Red,Green,Blue
};
在这个示例中,Color
是枚举类型的名称,Red
、Green
和 Blue
是枚举值。默认情况下,Red
的值为 0
,Green
的值为 1
,Blue
的值为 2
。
自定义枚举值:
你还可以为枚举值指定特定的整数值:
enum Status {Success = 0,Error = 1,Unknown = -1
};
3.2.2 枚举的使用
1> 声明
Color myColor;
myColor = Red; // 将枚举值赋给变量
2> 条件语句中使用
if (myColor == Green)
{// 处理绿色的情况
}
3.2.3 使用枚举的例子( 类名::枚举成员
)
-
在一个类中定义了枚举成员,类的实例化对象可以通过
类名::枚举成员
的方式来引用该枚举值。 -
这种方式能够清晰地表明枚举值的所属类,有助于提高代码的可读性。
下面是一个具体的示例:
#include <iostream>class MyClass
{
public:// 定义枚举类型 Colorenum Color {Red,Green,Blue};
};int main() {// 直接通过类名引用枚举值MyClass::Color myColor = MyClass::Green;// 根据颜色值输出不同的信息switch (myColor) {case MyClass::Red:std::cout << "The color is Red." << std::endl;break;case MyClass::Green:std::cout << "The color is Green." << std::endl;break;case MyClass::Blue:std::cout << "The color is Blue." << std::endl;break;}return 0;
}
3.2.3 枚举的范围和作用域
在 C++11 及之后的版本中,可以使用 强枚举(enum class
),它提供了更好的作用域控制和类型安全:
enum class Fruit
{Apple,Banana,Orange
};Fruit myFruit = Fruit::Apple; // 访问枚举值需要指定作用域
3.2.4 强枚举的优点
- 类型安全:强枚举不会隐式转换为整数类型,防止错误使用。
- 作用域控制:枚举值属于其定义的枚举类型,避免名称冲突。
3.3 运算符::
的使用
-
运算符
::
的分类总结,涵盖静态成员、命名空间成员、枚举或常量、基类成员,并进行了合并说明。 -
运算符
::
是作用域解析运算符,用于访问特定作用域中的成员,如类、命名空间、枚举等。
3.3.1 静态成员
-
定义: 属于类本身而非某个实例的成员,所有实例共享同一份数据。
-
访问方式:
类名::静态成员名
-
示例:
cpp复制代码class MyClass { public:static int count; // 静态成员变量声明 };int MyClass::count = 0; // 静态成员变量定义
3.3.2 命名空间成员
-
定义: 用于组织代码,避免命名冲突,可以包含函数、变量等。
-
访问方式:
命名空间名::成员名
-
示例:
cpp复制代码namespace MyNamespace {int value = 42; // 命名空间中的变量 }int val = MyNamespace::value; // 访问命名空间中的变量
3.3.3 枚举或常量
-
定义: 枚举是一种用户自定义类型,包含一组命名的整型常量。常量是固定值。
-
访问方式:
类名::枚举值
或命名空间名::枚举值
-
示例
:
class MyClass { public:enum Color { Red, Green, Blue }; // 枚举定义 };MyClass::Color c = MyClass::Red; // 访问枚举值
3.3.4 基类成员
-
定义: 基类是派生类的父类,基类成员可以是数据成员或成员函数。
-
访问方式:
基类名::成员名
(特别是在派生类中使用) -
示例:
class Base { public:void show() { std::cout << "Base" << std::endl; } };class Derived : public Base { public:void show() { std::cout << "Derived" << std::endl; }void display() {Base::show(); // 访问基类的 show 方法} };
3.3.5 总结
-
作用域:
::
运算符用于明确访问不同作用域中的成员,避免命名冲突。 -
共享性: 静态成员是类共享的,命名空间和枚举值是全局可见的,基类成员可通过派生类访问。
名`(特别是在派生类中使用) -
示例:
class Base { public:void show() { std::cout << "Base" << std::endl; } };class Derived : public Base { public:void show() { std::cout << "Derived" << std::endl; }void display() {Base::show(); // 访问基类的 show 方法} };