这个成语是什么,什么时候应该使用?它解决了哪些问题?当使用C++ 11时,成语是否会改变?
虽然在许多地方已经提到过,但我们没有任何单一的"它是什么"问题和答案,所以在这里.以下是前面提到的地方的部分列表:
c++ c++-faq copy-constructor assignment-operator copy-and-swap
因此,在观看了关于右值引用的精彩演讲之后,我认为每个类都会受益于这样的"移动构造函数",template<class T> MyClass(T&& other) 编辑,当然还有"移动赋值运算符",template<class T> MyClass& operator=(T&& other)正如Philipp在他的回答中指出的,如果它已经动态分配成员,或通常存储指针.就像你应该有一个copy-ctor,赋值运算符和析构函数,如果之前提到的点适用.思考?
我正在阅读Herb Sutter的"Exceptional C++"一书,在那本书中我学到了关于pImpl的习语.基本上,我们的想法是为a的private对象创建一个结构class并动态分配它们以减少编译时间(并且还以更好的方式隐藏私有实现).
例如:
class X
{
private:
C c;
D d;
} ;
Run Code Online (Sandbox Code Playgroud)
可以改为:
class X
{
private:
struct XImpl;
XImpl* pImpl;
};
Run Code Online (Sandbox Code Playgroud)
并且,在CPP中,定义:
struct X::XImpl
{
C c;
D d;
};
Run Code Online (Sandbox Code Playgroud)
这看起来很有趣,但我以前从未见过这种方法,既没有在我工作的公司,也没有在我看过源代码的开源项目中.所以,我想知道这种技术真的在实践中使用了吗?
我应该在任何地方使用它,还是谨慎使用?这种技术是否建议用于嵌入式系统(性能非常重要)?
我正在尝试部署(发布到公共)我最近制作的一个简单的qt应用程序,但却陷入静态链接qt库.
我按照qt docs上的指南来静态重建qt和我的应用程序.但是发布版本仍然需要qtgui/qtcore dll没有明显的原因,我想知道以前有没有人见过这种问题?或者甚至更好,已成功解决了吗?
可能标题问题不是很明确.我在Windows7上使用Qt5.
在一个线程(QThread)中,在"process()"函数/方法中,我必须等待"encrypted()"属于我在此线程中使用的QSslSocket 的SIGNAL.另外我想我应该使用QTimer并等待"timeout()"SIGNAL,以避免在无限循环中被阻塞......
我现在拥有的是:
// start processing data
void Worker::process()
{
status = 0;
connect(sslSocket, SIGNAL(encrypted()), this, SLOT(encryptionStarted()));
QTimer timer;
connect(&timer, SIGNAL(timeout()), this, SLOT(timerTimeout()));
timer.start(10000);
while(status == 0)
{
QThread::msleep(5);
}
qDebug("Ok, exited loop!");
// other_things here
// .................
// end other_things
emit finished();
}
// slot (for timer)
void Worker::timerTimeout()
{
status = 1;
}
// slot (for SSL socket encryption ready)
void Worker::encryptionStarted()
{
status = 2;
}
Run Code Online (Sandbox Code Playgroud)
好吧,显然它不起作用.它永远停留在那个循环中......
所以,问题是:有没有办法解决这个问题?我怎么能等待那个"encrypted()"SIGNAL但不要超过 …
几乎每个QtWidgets类都可以拥有父级.通常,在对象初始化时设置父级是可选的.例如,如果我创建一个继承QWidget类的类,我将在构造函数上执行以下操作:
Widget::Widget(QWidget* parent): QWidget(parent) {
hbox = new QHBoxLayout(this);
yes_button = new QPushButton("&Yes");
no_button = new QPushButton("&No", this);
cancel_button = new QPushButton("&Cancel", hbox);
}
Run Code Online (Sandbox Code Playgroud)
我可以设置或不设置父级.我可以cancel_button成为一个孩子hbox.我也可以cancel_button成为一个孩子yes_button,但我认为这是一件坏事.
这有什么意义?而且,是否真的有必要为QWidget我创建的每个基类设置父级?
我担心在将来升级Qt 5.9下开发的小部件库是可能的,而不必重新编译已经使用它的代码.当然,我已经开始使用PImpl成语和它在这里和这里描述的Qt版本.
然而,在尝试调整我的代码时,我提出了这样的想法,即不是添加新的数据成员并将它们移动到单独的私有类,我可以使用Qt的信号/槽机制和lambda函数,并且只有局部变量.让我们用以下示例说明这个想法:
变式A:
class Foo : public QWidget
{
Q_OBJECT
public:
explicit Foo(QWidget *parent = nullptr);
private:
// A bunch of data members
QPushButton *m_button;
QLineEdit *m_lineEdit;
QCheckBox *m_checkBox;
QString m_str;
private slots:
void on_pushButtonClicked();
void on_checkBoxStateChanged(int state);
};
Foo::Foo(QWidget *parent) :
QWidget(parent),
m_button(new QPushButton("Click me", this));
m_lineEdit(new QLineEdit(this)),
m_checkBox(new QCheckBox(this)),
m_str("Initial text")
{
connect(button, &QPushButton::clicked, this, &Foo::on_pushButtonClicked);
connect(checkBox, &QCheckBox::stateChanged, this, &Foo::on_checkBoxStateChanged);
}
Foo::on_pushButtonClicked()
{
m_str = m_lineEdit->text();
m_lineEdit->setDisabled(m_checkBox->isChecked());
}
Foo::on_checkBoxStateChanged(int state)
{ …Run Code Online (Sandbox Code Playgroud) 一个QWidget作为一个paintEvent函数,它是负责他的绘画.要正确实现此功能,QStyle对象用于表示每个组件,QStyleOption对象用于保存控件的状态.
例如:一个自定义ScrollBar工具paintEvent,drawComplexControl用" CC_ScrollBar" 选项调用.然后,QProxyStyle可以扩展以更改滚动条的外观.
当用户悬停滑块时,paintEvent调用它会应用新的"悬停"外观,该状态保存在QStyleOption::state.但是对于现在的一天小部件,这个状态不应该立即更新,而是在大约100-500毫秒的平滑过渡(动画).为了使用此转换为窗口小部件设置动画,需要一些值,例如滚动的每个部分的动画的当前状态(a qreal/ QColor?):顶部箭头,底部箭头或滑块.
在这个"漫长"的介绍之后,我的问题来了:
是否有某个变量来设置此动画的状态?我可以QStyleOption使用这个新值进行扩展,但是当前的实现似乎已经包含了动画,我无法找到保存此转换状态的位置.
我正在寻找一个规范的答案.
注意:为了避免"可能重复...",即使稍微相关,这也不是关于如何使用QAnimation或创建自定义小部件的问题.
通常,在编写 C++ 代码时,我会将对象始终作为普通属性保存,从而利用 RAII。然而,在 QT 中,删除对象的责任可以在QObject. 所以,假设我们定义了一些特定的小部件,那么我们有两种可能性:
1)使用QT的系统
class Widget1 : QWidget
{
Q_OBJECT
public:
Widget1(QWidget* parent = nullptr);
private:
QPushButton* myButton; // create it with "new QPushButton(this);"
};
Run Code Online (Sandbox Code Playgroud)
2)使用RAII
class Widget2 : public QWidget
{
Q_OBJECT
public:
Widget2(QWidget* parent = nullptr);
private:
QPushButton button; // normal RAII
};
Run Code Online (Sandbox Code Playgroud)
通常,我使用第一种方法。如果父母不仅通过布局了解其孩子,似乎有些事情会更好。但是仔细想想……真正的原因我还不是很清楚。
我知道堆栈是有限的。但是,假设这在这里不起作用。毕竟,堆栈不是那么小。
我正在寻找 Qt 智能指针的最佳实践。假设我有这样的事情。
void aFunction() {
QSharedPointer<QVector<QSharedPointer<Object> > > pointer = QSharedPointer<QVector<QSharedPointer<Object> > >(new QVector<QSharedPointer<Object> >);
doSomethingWithPointer(pointer);
changeOwnership(pointer);
}
Run Code Online (Sandbox Code Playgroud)
然后在 doSomethingWithPointer 函数中
void doSomethingWithPointer(QSharedPointer<QVector<QSharedPointer<Object> > > pointer) {
pointer->append(QSharedPointer<Object>(new Object);
}
Run Code Online (Sandbox Code Playgroud)
现在我在 doSomethingWithPointer 之后,将指针传递给 changeOwnership,它应该拥有它的所有权。我想知道的是 doSomethingWithPointer。在这样的函数中传递共享指针可以吗?或者我应该使用 QWeakPointer 因为 doSomethingWithPointer 实际上并不拥有指针的所有权?我什么时候应该使用 QWeakPointer?
c++ ×8
qt ×7
c++11 ×2
c++-faq ×1
constructor ×1
deployment ×1
lambda ×1
oop ×1
parent ×1
pimpl-idiom ×1
qstyle ×1
qt5 ×1
qtwidgets ×1
qwidget ×1
static ×1
timer ×1
transitions ×1
wait ×1
windows ×1