Qt4.7中 默认的构造函数

本文详细解析了C++中构造函数的默认参数使用规则,通过具体实例展示了如何正确设置默认参数,并解释了默认参数必须位于参数表最右侧的原因。同时,通过对比不同构造函数设置方式带来的影响,帮助读者深入理解C++构造函数的灵活性和复杂性。
<p><span style="font-size: medium;">初学Qt,发现每个例子自带的构造函数:</span></p>
<p><span style="font-size: medium;">Network.h头文件</span></p>
<p>?</p>
<pre name="code" class="cpp">#include "NetServerThread.h"

class Network : public QObject
{
Q_OBJECT

public:
Network(QObject *parent = 0); //因为QObject *parent为默认参数已经赋值,所以此构造
//函数为 Network类的默认构造函数
~Network();
};</pre>
<p>?Network.cpp</p>
<p>?</p>
<p>?</p>
<pre name="code" class="cpp">#include "NetServerThread.h"

Network::Network(QObject *parent)//这里写的构造函数的参数是为了初始化QObject参数parent,
:QObject(parent) //这样它可以继承父类QObject初始化的所有数据。
{ //该默认构造函数,实例化类时候只需要 Network network;
qDebug()<<"构造器开始";
//初始化对象
init();

}

Network::~Network()
{
}</pre>
<p>?</p>
<p><span style="font-size: medium;">?实例化Network类的时候,只需要</span></p>
<p><span style="font-size: medium;">Network network;</span></p>
<p><span style="font-size: medium;">即可调用默认构造函数,不需要写默认参数QObject* parent的值</span></p>
<p>?</p>
<p>?</p>
<p>?</p>
<div class="quote_title"><br>
<div class="quote_div">“默认实参必须是函数参数表中最右边(尾部)的参数<br>调用具有两个或多个默认实参数的函数时,如果省略的不是参数表中最右边的参数,则该参数右边的所有参数也应省略<br>默认实参应在函数名第一次出现时指定,通常是在函数原型中”
<p>?</p>
<p>?<span style="font-size: small;">比如说下面的函数</span></p>
<p><span style="font-size: small;">int fun(int a,int b,int c=3)</span></p>
<p><span style="font-size: small;">{</span></p>
<p><span style="font-size: small;"><br></span></p>
<p><span style="font-size: small;">}</span></p>
<p><span style="font-size: small;">c就是指定的默认实参,通常在函数原型中指定。这里给了3作为默认参数。用平常的时候调用这个函数fun(4,5,6);那么就是a=4,b=4,c=6。如果这样调用fun(1,2)那么就是a=1,b=2,c=3,这里c没有指定,因为c是默认实参,已经有了默认值,这里c就是采用默认值3。</span></p>
<p><span style="font-size: small;">为什么默认实参必须是函数参数表中最右边的参数。把上面的函数改下</span></p>
<p><span style="font-size: small;">int fun(int a=3,int b,int c)</span></p>
<p><span style="font-size: small;">{}</span></p>
<p><span style="font-size: small;">这样调用fun(1,2),这样就是a=1,b=2,而c根本就没有赋到值,就出错了。这些参数都是一一对应的。</span></p>
<p>?</p>
<p>?</p>
<p>?</p>
<p>参考文章:</p>
<p><a style="color: #000000; text-decoration: none; font-family: 'Microsoft YaHei'; font-size: 20px; line-height: 30px; text-align: left;" title="C/C++--C++默认参数及其所引起的二义性" href="http://blog.youkuaiyun.com/wudemiao1246403394/article/details/6992487">C/C++--C++默认参数及其所引起的二义性</a></p>
<p><a href="http://blog.sina.com.cn/s/blog_6340cd9c0100rabk.html"></a></p>
<h2 id="t_6340cd9c0100rabk" class="titName SG_txta"><a href="http://blog.sina.com.cn/s/blog_6340cd9c0100rabk.html">QT构造函数中*parent</a></h2>
<p><a href="http://blog.sina.com.cn/s/blog_6340cd9c0100rabk.html"><span>?</span></a></p>
<p>?</p>
<p>?</p>
<p>?</p>
<p>?</p>
<think>我们正在讨论的是Qt环境中的C++编程,但请注意:`vector`是C++标准库的一部分,与Qt无关。不过,在Qt中我们同样可以使用`std::vector`。用户的问题是在Qt结构体中如何给`vector<double>`赋值。 根据用户的问题,我们忽略引用中关于QList的讨论,因为用户明确使用`std::vector`。 在Qt的结构体中给`vector<double>`赋值,与在普通C++结构体中的赋值没有区别。我们可以通过以下几种方式赋值: 1. **直接初始化**:在结构体定义时,可以给成员变量一个默认值(C++11及以上支持)。 2. **构造函数初始化**:为结构体定义构造函数,在构造函数中初始化vector。 3. **外部赋值**:创建结构体实例后,通过实例访问成员vector,然后使用`push_back`、赋值运算符等赋值。 下面分别给出示例: ### 1. 直接初始化(C++11及以上) ```cpp #include <vector> struct MyStruct { std::vector<double> values = {1.0, 2.0, 3.0}; // 直接初始化 }; ``` ### 2. 构造函数初始化 ```cpp #include <vector> struct MyStruct { std::vector<double> values; MyStruct() : values({1.0, 2.0, 3.0}) { // 使用初始化列表 // 或者在构造函数体内赋值 // values = {1.0, 2.0, 3.0}; } }; ``` ### 3. 外部赋值 ```cpp #include <vector> struct MyStruct { std::vector<double> values; }; int main() { MyStruct s; // 方法1:逐个添加 s.values.push_back(1.0); s.values.push_back(2.0); s.values.push_back(3.0); // 方法2:使用初始化列表赋值(需要C++11) s.values = {1.0, 2.0, 3.0}; // 方法3:使用循环赋值 double arr[] = {1.0, 2.0, 3.0}; s.values.assign(arr, arr + 3); return 0; } ``` 注意:在Qt中,我们通常使用C++11或更高版本,因此推荐使用初始化列表的方式,代码更简洁。 如果用户需要在Qt的信号槽机制中使用这个结构体,需要注意将该结构体注册为Qt的元类型(使用`Q_DECLARE_METATYPE`和`qRegisterMetaType`),但这不是赋值的问题,而是跨线程传递等场景需要的。 因此,针对用户的问题,我们给出在Qt结构体中给`vector<double>`赋值的几种方法,用户可以根据具体情况选择。 如果用户的结构体需要被Qt的元对象系统识别(例如用于信号槽传递自定义类型),那么还需要注意结构体必须可拷贝构造,并且使用`Q_DECLARE_METATYPE`声明。但赋值本身与普通C++结构体赋值相同。 下面是一个在Qt中使用的完整示例(假设使用C++11或更高版本): ```cpp #include <vector> #include <QDebug> // 定义结构体 struct MyData { std::vector<double> values; // 默认构造函数,初始化vector MyData() : values({0.0, 0.0}) {} // 初始化为两个0.0 // 也可以提供带参数的构造函数 MyData(const std::initializer_list<double>& initList) : values(initList) {} }; // 如果需要在信号槽中使用,则注册(这里仅展示注册,实际使用需要在某个地方调用qRegisterMetaType) // 注意:在注册之前,必须使用Q_DECLARE_METATYPE声明 Q_DECLARE_METATYPE(MyData) int main() { // 使用默认构造函数 MyData data1; qDebug() << "Data1:"; for (double d : data1.values) { qDebug() << d; } // 使用初始化列表构造 MyData data2 = {1.1, 2.2, 3.3}; qDebug() << "Data2:"; for (double d : data2.values) { qDebug() << d; } // 外部赋值 data2.values = {4.4, 5.5}; qDebug() << "After assignment, Data2:"; for (double d : data2.values) { qDebug() << d; } return 0; } ``` 注意:如果用户使用的是较旧的C++标准(如C++98),则不能使用初始化列表,需要采用其他方式,比如在构造函数体内用循环赋值,或者使用`assign`等。 由于用户的问题是在Qt中,我们假设用户使用的是支持C++11的Qt版本(Qt5及以上通常都支持)。 因此,总结赋值方法: 1. 在结构体内部直接初始化(C++11) 2. 在结构体的构造函数中初始化 3. 在创建结构体实例后,通过成员访问进行赋值 用户可以根据自己的需求选择合适的方式。</think>在 Qt 结构体中为 `std::vector<double>` 赋值的方法与标准 C++ 一致,以下是几种常用方法及完整示例: ### 1. **直接初始化赋值** ```cpp #include <vector> struct SensorData { std::vector<double> readings; }; int main() { SensorData data; // 直接初始化赋值 data.readings = {1.5, 2.8, 3.2, 4.7}; // C++11 初始化列表 } ``` ### 2. **通过成员函数赋值** ```cpp SensorData data; // 使用 push_back 逐个添加 data.readings.push_back(1.5); data.readings.push_back(2.8); // 使用 assign 批量赋值 double raw[] = {3.2, 4.7, 5.1}; data.readings.assign(raw, raw + 3); // 从数组复制 ``` ### 3. **结构体构造函数初始化** ```cpp struct SensorData { std::vector<double> readings; // 构造函数初始化 SensorData(const std::vector<double>& vals) : readings(vals) {} }; int main() { // 创建时直接初始化 SensorData data({1.5, 2.8, 3.2}); // 调用构造函数 } ``` ### 4. **循环赋值** ```cpp SensorData data; // 预留空间优化性能 data.readings.reserve(100); for (int i = 0; i < 100; ++i) { data.readings.push_back(i * 0.1); // 循环赋值 } ``` ### 完整 Qt 示例 ```cpp #include <QDebug> #include <vector> struct SensorData { std::vector<double> readings; QString sensorName; }; int main() { SensorData tempSensor; tempSensor.sensorName = "Temperature"; // 赋值方法1:初始化列表 tempSensor.readings = {23.5, 24.1, 25.3}; // 赋值方法2:追加数据 tempSensor.readings.push_back(26.0); // 输出验证 qDebug() << "Sensor:" << tempSensor.sensorName; qDebug() << "Readings:"; for (double val : tempSensor.readings) { qDebug() << val; } return 0; } ``` ### 关键点说明 1. **内存优化**: - 使用 `reserve()` 预分配空间避免多次扩容 - 大数据量时优先用 `assign()` 而非多次 `push_back()` ```cpp data.readings.reserve(1000); // 预分配 data.readings.assign(rawData.begin(), rawData.end()); ``` 2. **Qt 特性兼容**: - 结构体需注册元类型才能用于信号槽 ```cpp Q_DECLARE_METATYPE(SensorData) ``` 3. **性能提示**: - 移动语义优化大向量赋值 ```cpp data.readings = std::move(newReadings); // C++11 移动赋值 ``` ### 输出示例 ``` Sensor: "Temperature" Readings: 23.5 24.1 25.3 26.0 ``` [^1]: 引用中提到了容器初始化差异,但 `std::vector` 支持直接初始化赋值,而 Qt 的 `QList` 需要替代方案。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值