??xml version="1.0" encoding="utf-8" standalone="yes"?> @w.cn邮箱注册地址Q?br />
https://domains.live.com/members/signup.aspx?domain=w.cn @9.cn邮箱注册地址Q?br />
https://domains.live.com/members/signup.aspx?domain=9.cn
]]>
]]>
]]>
]]>
]]>
一 服务?br />使用QTcpServerc?br />QTcpServer *tcpServer = new QTcpServer(this);
开启监?br />tcpServer->listen(QHostAddress::LocalHost, port); //port为端口号
如果监听p|, h看tcpServer->errorString();
可以q接tcpServer对象的newConnection信号, q样一有客L(fng)q接上来, 可以调用我们的q接槽进行处?br />connect(tcpServer, SIGNAL(newConnection), this, SLOT(slotNewClientConnect()));
当断开监听? 可以先判断单前是否在监听
tcpServer->isListening(), 若果? 则调用tcpServer->close();关闭监听
当客L(fng)q接上来的时? 可以调用tcpServer->nextPendingConnection();来允许客L(fng)q接, q返回客L(fng)的socket对象
可以对连接上来的socket对象q行信号-槽关? q样可以对q个客户端的socket对象q行更多的控?br />
?客户?br />使用QTcpSocket对象q接到服务器
QTcpSocket *tcpSocket = new QTcpSocket(this);
tcpSocket->abort(); //取消已有的连?br />tcpSocket->connectToHost(服务器ip, 服务器端?;
可以兌tcpSocket的error信号, q样q接p|时候就可以得到通知?br />可以兌tcpSocket的readyRead()信号, q样接收到数据时候也可以得到通知?br />同样connected()信号提示已成功连接到服务?br />disconnected()信号提示已经断开q接, 可以兌到该对象的deleteLater()槽上删除q接(服务?
q样, 只要得到通讯的socket对象, 兌一下readyRead()信号可以读取连接端发送过来的数据, 写的话直接调用writeҎ(gu)卛_
写数据发送可以用QByteArray和QDataStreamq行操作:
QDataStream对象可以对QByteArray对象q行d操作
比如Q?br />QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0); //要设|版? 版本可和接受端d版本号一?br />out << (quint16)0; //写要发送数据的长度, q里先用0写前面两个字节占? 后面再补上来
out << tr("发送的数据");
out.device()->seek(0); //又蟩到缓冲区的开? 准备些数据包的长?br />out << (quint16)(block.size() - sizeof(quint16));
然后使用q接套接字对?conObj->write(QByteArray对象); q样把数据发送出M, ?br />conObj->write(block);
dq接端发送过来的数据
同样用QDataStream来处?
QDataStream in(q接端套接字对象);
in.setVersion(QDataStream::Qt_4_0); //要和发送端的版本号一?br />
qint16 blockSize = 0; //初始?
if(0 == blockSize)
{
if(conSocket->bytesAvailable() < (int)sizeof(quint16)) //如果已经接收到的数据于2个字?
{ //说明数据q没接收完,直接退出,{待数据接收完全
return;
}
in >> bIockSize; //保存数据包大?两个字节)
}
if(conSocket->bytesAvailable() < blockSize)
{//接收到的数据不完?br /> return;
}
in >> message; //QString message; 把接收到的数据存攑ֈmessage对象里面
q样ok?br />
//取得本地ip地址信息
QString localHostName = QHostInfo::localHostName();
QHostInfo info = QHostInfo::fromName(localHostName);
qDebug() << "localHostName:" << localHostName << endl
<< "IP Address:" << info.addresses();
]]>
1.用Qt Creator创徏一个基于GUI的应用程? 选择基类有QWidget, QDialog, QMainWindow三种. 发现一个问? 当选择用QWidget, QDialog? 可以直接在派生类的构造函数里创徏控gd到布局理器对? 然后调用setLayout(布局理器对?可以在界面昄创徏好的控g? 然而选用QMainWindow作ؓ(f)基类的时? q样操作却没有显C出控g? l过癑ֺ, 发现原来zc还要创Z个QWidget对象, 把布局理器放到这个QWidget对象上面, 然后把这个QWidget对象作ؓ(f)参数调用setCentralWidget可以正常显C控件了.
2.解决Qt中显CZ文ؕ码的Ҏ(gu), q里直接d两个Ҏ(gu)的调?QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale());
3.H口样式
4.md5加密
QCryptographicHash test(QCryptographicHash::MD5);
QByteArray data;
data.append(tr("test"));
test.addData(data);
QByteArray result = test.result();
result.toBase64(); //密文用base64~码
result.toHex(); //?6q制昄数据
5.使用多线E?br />l承QThread, 重写run虚方? 如果使用U程事g循环, 在run里面使用QObject对象q用connect兌信号, 需要在构造函数里调用
6.
wchar_t* wptr = L"test";
QString ret = QString::fromWCharArray(wptr);
QString ret2 = QString((QChar*)wptr, wcslen(wptr));
QString 转wchar_t*
wchar_t szBuf[1024];
QString str = tr("hello");
wcscpy_s(reinterpret_cast<wchar_t*>(szBuf),
sizeof(szBuf) / sizeof(wchar_t),
reinterpret_cast<const wchar_t*>(str.utf16()));
7.
8.对话框屏q居中显C?br /> quint32 scrheight = QApplication::desktop()->height();
quint32 width = this->width();
quint32 height = this->height();
this->move((scrwidth - width) / 2, (scrheight - height) / 2);
9.发送信L(fng)时? 一些类型作为参? 需要注?10.rcc资源文g
bin目录下有个rcc.exe工具, 可以吧qrc脚本~译成rcc资源2q制文g, 命o(h)如下:
rcc -binary xxx.qrc -o xxx.rcc
在程序中引用q个rcc资源文g:
QResource::registerResource("xxx.rcc");
卸蝲
QResource::unregisterResource("xxx.rcc")
]]>
QMovie *obj = new QMovie("xxx.gif");
labObj->setMovie(obj);
obj->start();
]]>
]]>
把该删的删除, ok?br />
记得备䆾..
]]>
? 思\是q样, q里上关键代码吧
FunSetLayeredWindowAttributes funSetLayeredWindowAttributes;
funSetLayeredWindowAttributes = (FunSetLayeredWindowAttributes)GetProcAddress(GetModuleHandle("user32.dll"), "SetLayeredWindowAttributes");ModifyStyleEx(NULL, 0x80000/*WS_EX_LAYERED*/); //H口要有WS_EX_LAYERED属性才能用讄透明的那个API
同样, 在OnCancelҎ(gu)里面d一个定时器, Z把IDT_SHOW定时器给KILL?br />
SetTimer(IDT_EXIT, 50, NULL);
OnTimerҎ(gu)q样?
{
case IDT_SHOW:
funSetLayeredWindowAttributes(this->m_hWnd, 0, m_current % 255, 2);
m_current += 5;
if(m_current >= 255)
KillTimer(IDT_SHOW);
break;
case IDT_EXIT:
m_current -= 5;
funSetLayeredWindowAttributes(this->m_hWnd, 0, m_current % 255, 2);
if(m_current <= 5)
{
CDialog::OnCancel();
KillTimer(IDT_EXIT);
}
break;
}
很简单吧, 一个E入浅出效果就出来?br />
?
static控g背景透明
dWM_CTLCOLOR消息映射
d响应函数
实现响应函数
{
pDC->SetBkMode(TRANSPARENT);
return (HBRUSH)::GetStockObject(NULL_BRUSH);
}
q里, 装了一个基c? 方便以后?br />FadeIODlg.h
class CFadeIODlg : public CDialog
{
DECLARE_MESSAGE_MAP()
public:
CFadeIODlg(UINT uDLGID, CWnd* pParent = NULL);
virtual ~CFadeIODlg();
protected:
virtual void DoDataExchange(CDataExchange* pDX);
virtual void OnCancel();
virtual void OnOK();
afx_msg BOOL OnInitDialog();
afx_msg void OnTimer(UINT nIDEvent);
private:
enum{ TIME_BEGIN = 100, TIME_END = 101};
typedef BOOL (__stdcall *FUNSetLayeredWindowAttributes)(HWND hwnd, COLORREF crKey, BYTE bAlpha, DWORD dwFlags);
FUNSetLayeredWindowAttributes m_funTransparent;
enum{
MAX_TRANSPARENT = 255, //最大透明?/span>
NUM_BEGIN = 10, //开始计时器旉间隔
NUM_END = 10, //l束计时器时间间?/span>
NUM_CHANGE = 5, //改变透明?/span>
};
int m_currentTransparent; //当前H口透明?/span>
};
FadeIODlg.cpp
#include "UI.h"
#include "FadeIODlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
CFadeIODlg::CFadeIODlg(UINT uDLGID, CWnd* pParent /* = NULL */)
: CDialog(uDLGID, pParent)
{}
CFadeIODlg::~CFadeIODlg()
{}
void CFadeIODlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CFadeIODlg, CDialog)
ON_WM_TIMER()
END_MESSAGE_MAP()
BOOL CFadeIODlg::OnInitDialog()
{
CDialog::OnInitDialog();
ModifyStyleEx(0, 0x80000);
m_currentTransparent = 0;
m_funTransparent = (FUNSetLayeredWindowAttributes)GetProcAddress(GetModuleHandle("User32.dll"), "SetLayeredWindowAttributes");
if(m_funTransparent)
{
//m_funTransparent(this->GetSafeHwnd(), 0, 0, 2);
SetTimer(TIME_BEGIN, NUM_BEGIN, NULL);
}
return TRUE;
}
void CFadeIODlg::OnTimer(UINT nIDEvent)
{
switch(nIDEvent)
{
case TIME_BEGIN:
if(m_currentTransparent <= MAX_TRANSPARENT)
{
m_funTransparent(this->GetSafeHwnd(), 0, m_currentTransparent, 2);
m_currentTransparent += NUM_CHANGE;
}
else
KillTimer(TIME_BEGIN);
break;
case TIME_END:
if(m_currentTransparent >= 0)
{
if(m_currentTransparent > MAX_TRANSPARENT)
m_currentTransparent = MAX_TRANSPARENT;
m_funTransparent(this->GetSafeHwnd(), 0, m_currentTransparent, 2);
m_currentTransparent -= NUM_CHANGE;
}
else
{
KillTimer(TIME_END);
CDialog::OnCancel();
}
break;
}
}
void CFadeIODlg::OnOK()
{
}
void CFadeIODlg::OnCancel()
{
if(m_funTransparent)
{
KillTimer(TIME_BEGIN);
SetTimer(TIME_END, NUM_END, NULL);
}
else
CDialog::OnCancel();
}
ok, 完成, 以后直接l承q个对话? E微修改一? 效果出来了
]]>
]]>
然后, 当我在对话框工程退出的时? 发现q个ExitInstanceҎ(gu)q没有被调用, 我就有些p涂, baidu+google, ...
然后, 我就? 我添加一个appcȝ析构Ҏ(gu)了, 但发现这个析构函数还是诡异的没被调用...
theApp原本是一个全局对象, 它的构造和析构原本是CRT库来处理?br />
后来发现, 只要在theApp对象的成员I(y)nitInstanceҎ(gu)q回TRUE(默认是返回FALSE)可以成功的调用ExitInstance和析构函C
ok, 诡异的InitInstanceq回FALSE? ׃?x)调用theApp对象的析?
]]>
配置好库环境? 下面写出使用GDI Plus的基本步?
1.包含头文?br />#include <gdiplus.h>
2.使用名字I间
using namespace Gdiplus;
3.q接必要的导入库文g
#pragma comment(lib, "gdiplus.lib")
4.初始?br />
]]>
google一? 原来只要装一下sp6补丁好?br />
q接地址
e文版: vs6sp6
中文? vs6sp6
]]>
通过d消息响应函数
afx_msg UINT OnNcHitTest(CPoint point);
d?br />ON_WM_NCHITTEST()
然后, 定义OnNcHitTest的行为即? OnNcHitTest的代码如?
{
CRect rect;
GetClientRect(rect);
ClientToScreen(rect);
if(rect.PtInRect(point))
return HTCAPTION;
return CDialog::OnNcHitTest(point);
}
首先, 发生WM_NCHITTEST消息的时? E序先取得客户区的窗口矩? q里用到GetClientRectҎ(gu)得到, ׃GetClientRect取得的是相对于窗口坐标系l? 但OnNcHitTest的参数point却是相对于屏q的坐标pȝ, 所以这里用CClientToScreen把取到的客户区矩形{成相对于屏幕的坐? 然后用CRectcȝPtInRectҎ(gu)判断point是否落在q个矩Ş里面, 如果? 则返回HTCAPTION(q当于q次点击是点?yn)L题栏), 所? 可以这h拖动H口? 如果, OnNcHitTest直接q回HTCAPTION的话, 那么, 但用L(fng)击非客户区的时? 有些功能?x)失? 比如点击pȝ的关闭按? 试一下就?x)发现这个按钮无效? ok, 如果点击的是非客L(fng), 者直接返回CDialog::OnNcHitTest(point), q就是按默认处理?
以上的这个方法比较麻? 其实可以更简单一? 只要先调用父cȝOnNcHitTest(point), 取得q回? 在判断是不是HTCLIENT, 如果? 则返回HTCAPTION, 否则直接q回父类OnNcHitTest(point)的返回值就ok? 修改后如?
{
UINT uRet = CDialog::OnNcHitTest(point);
if(HTCLIENT == uRet)
return HTCAPTION;
return uRet;
}
再简化一? 成q样?
{
UINT uRet = CDialog::OnNcHitTest(point);
return (HTCLIENT == uRet) ? HTCAPTION : uRet;
}
]]>
创徏可等待计时器内核对象, 可以实现cM功能, 现在, 下边l出如何使用可等待计时器内核对象
LPCWSTR pszWatchDogName,
DWORD dwPeriod,
DWORD dwWait,
DWORD dwDfltAction,
DWORD dwParam,
DWORD dwFlags
);
2.SetWaitableTimer
__in HANDLE hTimer,
__in const LARGE_INTEGER* pDueTime,
__in LONG lPeriod,
__in_opt PTIMERAPCROUTINE pfnCompletionRoutine,
__in_opt LPVOID lpArgToCompletionRoutine,
__in BOOL fResume
);
CreateWatchDogTimer函数是创徏一个可{待事g内核对象
SetWaitableTimer函数是讄内核对象的触发时间和旉间隔
废话不多说了, q里直接上代?br />
{
SYSTEMTIME st;
st.wYear = 2012;
st.wDay = 10;
st.wDayOfWeek = 0;
st.wHour = 20;
st.wMilliseconds = 0;
st.wMinute = 16;
st.wMonth = 5;
st.wSecond = 0;
FILETIME localft;
FILETIME utc;
SystemTimeToFileTime(&st, &localft);
LocalFileTimeToFileTime(&localft, &utc);
LARGE_INTEGER liUTC;
liUTC.LowPart = utc.dwLowDateTime;
liUTC.HighPart = utc.dwHighDateTime;
m_Timer = CreateWaitableTimer(NULL, FALSE, NULL);
SetWaitableTimer(m_Timer, &liUTC, 10 * 1000, NULL, NULL, FALSE);
}
void CDialogDemoDlg::ThreadProc2(CDialogDemoDlg* pDlg)
{
while(1)
{
DWORD ret = WaitForSingleObject(pDlg->m_Timer, INFINITE);
if(WAIT_OBJECT_0 == ret)
{
AfxMessageBox("可等待事件内核对象触?");
}
}
}
ThreadProc2是一个线E? 当时间一? WaitForSingleObject׃(x)q回, 因ؓ(f)q里创徏的是一个自动复位内核对? 说以WaitForSingleObjectq回是会(x)自动把内核对象复? q里为演C? 写了个死循环, 所? 下一ơ调用WaitForSingleObject? 如果旉未到, U程ȝ?x)被挂v.
具体用法l节, MSDN
参? windows核心~程
]]>
重蝲PostNcDestroy, 需要delete掉this指针
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDlgTest)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
virtual void PostNcDestroy();
//}}AFX_VIRTUAL
// Implementation
protected:
// Generated message map functions
//{{AFX_MSG(CDlgTest)
virtual void OnOK();
virtual void OnCancel();
//}}AFX_MSG
{
// TODO: Add extra validation here
}
void CDlgTest::OnCancel()
{
DestroyWindow();
}
void CDlgTest::PostNcDestroy()
{
// TODO: Add your specialized code here and/or call the base class
CDialog::PostNcDestroy();
delete this;
}
]]>
ps:以后用ATL写C(j)OMlg, 爽歪?br />ps:有空把COM技术内q看?br />
]]>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
FILETIME fTm;
SYSTEMTIME sysTm;
HANDLE hFile;
hFile = CreateFile("d:/test.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_ARCHIVE, NULL);
if(INVALID_HANDLE_VALUE == hFile)
{
cout << "no" <<endl;
}
GetLocalTime(&sysTm);
sysTm.wYear = 2013;
SystemTimeToFileTime(&sysTm, &fTm);
BOOL bRet = SetFileTime(hFile, &fTm, &fTm, &fTm);
int ret = GetLastError();
if(bRet)
{
cout << "ok" <<endl;
}
return 0;
}
主要调用SystemTimeToFileTime
]]>
int ifoo;
char cfoo[1024] = {"test"};
//...
#pragma data_seg()
.DataSegName READ WRITE SHARE
ps:之前用指?br />
q不是对编译的时? llink.exeE序传递一个参数而已?
link /dll /sections:.DataSegName ......
]]>
很多时? 看书都看不懂. 现在我懂? 不是我太W了, 是因为有些基q没打好. 因? 学习(fn)Ҏ(gu)不对? D了我费了好多时? 我太2? 学习(fn)要@序渐q嘛, 好比一个没过?sh)脑的h, 叫他一开始就dmfc, 那是不可能的. 而我? q道理是懂得? 有时候做事却没去惌什么道? 以ؓ(f)惛_, 有书可以? p? l果看了? C一脸灰, q把自己的信心给灭?太难? 怎么看都看不? 再网上跟一些网友交? ? 他们都能看懂, 我自卑啊~~
现在我明白了, 那是我还有些基础没学q? 但他们已l学扎实? 所? l过一些天的基学习(fn), 我再来学那些以前看似很难的东? 现在学v来就L多了.
(?..哥文W不? 不会(x)写作, 以上说的语无伦次, U当自己l笔作文? 希望以后能够写的好一? 句子看得通顺一?.....睡觉? 88)
]]>
{
TCHAR szBuf[4096];
GetClassName(hwnd, szBuf, sizeof(szBuf));
string str = szBuf;
if(!str.compare("#32770"))
{
HWND hSubWnd = GetDlgItem(hwnd, 0xffff);
if(hSubWnd)
{
int len = GetWindowText(hSubWnd, szBuf, sizeof(szBuf));
cout << "yes:" <<szBuf <<endl;
}
}
return TRUE;
}
int main()
{
EnumWindows(EnumWindowsProc, NULL);
return 0;
}
]]>
2.对于一个类的基cȝ数目, c++没有限制(可以多?
两个基类是最常见? 一个基cd常用于表CZ个共有抽象接? W二个基cL供是有的实现
从第三个或更多个直接基类l承而来的派生类遵@mixin-based设计风格
3.基类构造函数被调用的顺序以z表中声明的顺序ؓ(f)?/span>
4.在多l承? zcd以从两个或者更多个基类中承同名的成员 --直接讉K是二义的, 导致编译时刻错? 所以要昄指明调用哪个基类的哪个成?Base::member
5.publicz被称为类型?type inheritance) --zcL基类的子cd
提供了较一般的基类的一U特?/span>
6.privatez被称为实现?implementation hinheritance) --zcM直接支持基类的公有接? 提供了自q公有接口, 重用基类的实?/span>
private基类放映了一U?qZ子类型关p?的承Ş? 基类的整个公有接口在zcM变成private
7.对于is-a子类型关pL? publicl承是一个很有利的机?/span>
8.has-a关系一般由l合(composition)而不是承来支持 --使一个类UCؓ(f)另一个类的成?/span>
a:如果我们希望改写一个类的虚拟函? 则必M用私有承而不是用组?/span>
b:如果我们希望一个类能够引用"一个包含多U可能类型的层次l构"中的一个类, 那么必通过引用使用l合
c:如果只是希望单的重用实现, 则按值组合比l承更好
d:如果希望对象的迟~型分配, 按引?使用一个指?l合通常是一个不想的设计选择
9.免除(exempting)个别成员的私有承媄?/span>
以私有方式? 基类的所有protected和public成员全被l承为子cȝU有成员
c设计者可以针对基cȝ个别成员, 是其免除非公有派生的影响:
class CSub: private CBase {
public:
using CBase::Member;
};
免除个别成员的另一个原因是允许后箋的派生类讉KU有基类的protected成员
zcd能将l承得到的成员恢复到原来的访问? 该访问别不能比基类中原来指定的U别更严格或更不严格
10.protectedl承 --基类的所有公有成员都成ؓ(f)zcȝprotected成员
11.对象l合有两UŞ?/span>
a:按值组?Composition by value)
b:按引用组?Composttion by reference)
12.虚拟l承(virtual inheritance) --在虚拟承下, 只有一个共享的基类子对象被l承, 而无基类在派生层ơ中出现多少?/span>
׃n的基cd对象被称拟基c?vitual base class)
在虚拟承下, 基类子对象的复制?qing)由此引L(fng)二义性都被取消了
13.虚拟l承的语?
CSub: public virtual CBase1, public virtual CBase2 {...};
virtual ?public的顺序不重要
]]>
2.c++通过cL?class derivation)的机制来支持l承
3.基类(base class)
4.zc?derived class)
5.基类和派生类实例的集合称为类l承层次l构(hierarchy)
6.如果基类和派生类׃n相同的共有接? 则派生类被称做基cȝ子类?subtype)
7.基类指针或引用可以直接引用其Mz的类, 多?polymorphism)
8.在运行时刻需要解析出被调用的函数, q个解析q程被称为动态绑?dynamic bindng) --~省情况? 函数实在~译时刻被静态解析的
9.c++? 通过一U被UCؓ(f)虚拟函数(virtual function)的机制来支持动态绑? 通过集成和动态绑? 子类型多态性ؓ(f)面向对象的程序设计提供了基础
10.面向对象的程序设计提供了一U方? 把类型解析的负担从程序员的n上{Ud~译器上
11.cȝ承层ơ结构的主要好处? 我盟可以针对抽象基类的共有接口进E编E? 而不是针对组成承层ơ的个别cd
用户代码可以不受语言变化的媄?--多态和动态绑?/span>
12.在c++? 多态性只存在于子cȝ承层ơ中 --void*型的指针可以被描qCؓ(f)多? 但是语言本nq没有显C的支持他们, 必须q序员自己来管?/span>
c++语言通过几种方式支持多态?/span>
通过一个隐式{? ?zcL针或引用"转到"其共有基cȝ型的指针或引?
通过虚拟函数的机?/span>
通过dynamic_cast和typeid操作W?/span>
if(SubClass* pSub = dynamic_cast<SubClass*>(pObj)) ...
13.抽象基类(abstract base class)
14.实体基类(concrete base class)
15.U虚拟函?pure virtual function)
16.覆盖(override)
17.c++语言为我们提供了一U语法结? 通过它可以指? 一个虚拟函数只是提供了一个可以被子类改写的接?/span>
18.传递给~省函数的g是在q行时刻军_, 而是在编译时L据被调用函数的对象的cd军_
19.虚拟析构函数 --主要是ؓ(f)了能够用delete销毁基cȝ时候也能够保证调用zcȝ析构函数, 要不然它只是调用基类的析构函数而已
]]>
2.位单个类型提供手工生成的拯是一个无休止的过E? 也是一个无限复杂的l护q程
3.模板参数?template parameter list) --template<xxx> xxx是模板参数?/span>
4.模板的类型参?type parameter)由关键字class或关键字typename?qing)其后的表示W构?/span>
5.每个模板参数前面都必L关键字class或typename
6.模板非类型参?nontype parameter)׃个普通参数声明构? 一个非cd参数只是该参C表了一个潜在的? 而这个值又代表cL板定义中的一个参?
template<class Type, int size = 1024>
class Buffer;
//如果模板实例的名字没有指定Buffer的大? 则实例化Buffer的大是1024
7.cd转换的过E被UCؓ(f)模板实例?template instantiation)
从通用的类模板定义中生成类的过E?/span>
8.模板参数的缺省?/span>
template<class Type = string, int size>
class Buffer;
9.cL板成原函数可以再cL板的定义中定? 该成员函数是inline成员函数; 也可以定义在cL板定义之?/span>
10.c++的模板编译模?template compilation model)
]]>
2.c++要求, 赋?=), 下标([]), 调用(()), 和成员访问箭?->)操作W必被定义E类成员操作W? M把这些操作符定义为名字空间成员的定义都会(x)?/span>
标记为编译时刻错?/span>
3.c++预定义可重蝲的操作符:
+ - * / % ^ & | ~
! , = < > <= >= ++ --
<< >> == != && || += -= /=
%= ^= &= |= *= <<= >>= [] ()
-> ->* new new[] delete delete[]
4.对于内置cd的操作符, 它的预定义意义不能被改变
5.预定义的操作W优先不能被改?/span>
6.除了operator()? 对其他重载操作符提供~省实参都是非法?/span>
operator)的定?/span>
2.newcd?--只有new表达式成功的甌到空间内? 构造函数才?x)被调?/span>
3.构造函数定义ؓ(f)inline? 创徏对象是会(x)在调用点展开构造函?/span>
4.成员初始化列?member initialization list)
5.构造函C能用const或volatile关键字来声明
一个constcd象在"从其构造函数完成到析构函数开?q段旉内才被认为是const, volatilecd象也一?/span>
6.explicit修饰W通知~译器不要提供隐式{?/span>
void print(const CTest &test);
//...
print("oops"); //q种调用?x)?oops"转换成一个CTest对象
~省情况? 单参数构造函?或者有多个参数, 除了W一个参数外, 其他都有~省实参)被用作{换符
无意的隐式类转换, 是很难跟t的错误!, 关键字explicit被引入到标准c++? 以帮助我们抑制这U不受欢q的~译辅助行ؓ(f)
explicit只能被应用在构造函C
7.~省构造函数是不需要用h定实参就能够被调用的构造函? --q不意味着它不能接受实? 只意味着构造函数的每个参数都有一个缺省g之关?/span>
8.限制对象创徏 --把相x造函数放到非公有讉K区内, 从而限制或昄止某些形式的对创徏动作
在实际的c++E序? 非公有的构造函C要用处是:
防止用一个类对象惌cd一个对象做拯
指出只有当一个类在承层ơ中被用作基c? 而不能直接被应用E序操纵? 构造函数才能被调用
9.拯构造函?--用一个类对象初始化该cȝ另一个对象被UCؓ(f)~省按成员初始化(default memberwise initialization)
一个类对象惌cȝ另一个对象作拯是通过依次拯每个非静态数据成员来实现
c设计者可以通过提供Ҏ(gu)的拷贝构造函?copy constructor)来改变缺省的行ؓ(f)
拯构造函C一定是const, 但它却必L引用
10.无论何时, 当在一个函数内删除一个独立的堆对象时, 最好用auto_ptrcd象而不是一个实际的指针
如果delete表达式失? 如一个异常被抛出, ?x)到时内存泄?异常抛出, 跌了delete操作?), 不会(x)调用析构函数
所以徏议用auto_ptr指针
11.对于在堆中分配的cd象数l的元素, 我们没有办法提供一l显C的值来做初始化, 如果l化支持通过new表达式分配数l? 则类必须提供一个缺省的?/span>
造函? 或不提供构造函?/span>
12.用一个类对象初始化另一个类对象, UCؓ(f)按成员初始化(default memberwise initialization)
发生?用一个类对象昄的初始化另一个对?/span>
把一个类对象作ؓ(f)实参传递给一个函?/span>
把一个类对象作ؓ(f)一个函数的q回g递回?/span>
非空序容器cd的定?/span>
把一个类对象插入C个容器类型中
13.成员cd象初始化
14.~省按成员赋?default memberwise assignment) --用一个类对象向该cȝ另一个对象的赋值操?/span>
用隐式的拯赋值操作符
一般来所, 如果~省的按成员初始化对于一个类不合? 则缺省的按成员赋g不合?/span>
通过提供一个现实的拯赋值操作符的实? 可以改变~省的按成员赋?/span>
注意要防止一个类对象向自p?--对于"先释放与该对象当前相关的资源, 以便分配与被拯对象相关资源"q样的拷贝赋值操作符, 拯自n其?/span>
1.mfc支持两种U程
用户界面U程
工作U程
2.mfc中所有线E都是由CWinThread对象表示
CWinThread是用h口线E的基类, CWinApp是从CWinThreadz出来?/span>
在写用户接口U程? 也要从CWinThreadcL生出自己的线E类
可以调用AfxBeginThread函数, ?x)创建CWinThread对象
3.~写是想工作U程的控制函? 控制函数的原?
UINT ControlFunctionName(LPVOID pParam); //U程回调
4.U程调用AfxBeginThread函数可以创建新的线E?/span>
5.创徏q启动工作线E?
CWinThread* AfxBeginThread(
AFX_THREADPROC pfnThreadProc,
LPVOID pParam,
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0,
WORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);
6.AfxEndThreadl止U程
7.创徏用户界面U程
从CWinThreadcL生出自己的线E类
攚w这个类
启动用户界面
8.基类的一些成员函?
ExitInstance, 当线E退出是, ?x)调用执行清理工?/span>
InitInstance, 执行U程cd例初始化, 子类必须重写
OnIdle, 执行U程特定I闲旉处理
PreTranslateMessage, qo(h)消息
Run, 执行U程函数
9.AfxBeginThread函数的另一个重载原?(界面U程)
CWinThread* AfxBeginThread(
CRuntimeClass* pThreadClass, //用RUNTIME_CLASS宏将U程cL针{换ؓ(f)指向CRuntimeClass对象指针
int nPriority = THREAD_PRIORITY_NORMAL,
UINT nStackSize = 0;
DWORD dwCreateFlags = 0,
LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL
);
10.l止U程
正常l止U程 VOID PostQuitMessage(int nExitCode);
提前l止U程 在线E内调用AfxEndThread函数 VOID AfxEndThread(UINT nExitCode);
11.U程同步技?/span>
信号?--限制使用׃n资源的线E数?/span>
CSemaphore g_Sem(5, 5); 旉内最多只?个线E能׃n资源, q初始开始时没有U程获得信号资源
一旦线E访问共享资? 信号量计数器减1, 若变?, 则下来对资源的访问就?x)被拒? 知道持有的资源线E释放了资源的持有权
互斥对象 --内核对象
临界?--用户模式对象 弄不好就Ҏ(gu)出现死锁, 不过用v来很? 只有4个API
InitializeCriticalSection, EterCreiticalSection, LeveCriticalSection, DeleteCriticalSection
事g对象 --内核对象 分收工重|对象和自动重置对象
?/span>
10.cȝ定义不会(x)引v存储区分? 只有当定义一个类的对象时, pȝ才会(x)分配存储?/span>
11.每个cL员函数的拯只有一?/span>
12.把一个成员函数声明ؓ(f)const可以保证q个成员函数不修改类的数据成? 但是, 如果该类含有指针, 那么在const成员函数中就能修Ҏ(gu)针所指的对象,
~译器不?x)检ؓ(f)错误, q常o(h)c++初学者吃?/span>
13.Z允许修改一个类的数据成? 即它是一个const对象的数据成? 我们也可以把Ҏ(gu)据成员声明ؓ(f)mutable(易变?. mutable数据成员永远不会(x)?/span>
const成员, mutable成员中可以被更新
14.每个cL员函数都含有一个指向被调用对象的指? q个指针被称为this:
在非const成员函数? 它的cd是指向该cȝ型的指针
在const成员函数? 是指向constcȝ型的指针
在volatile成员函数? 是指向volatilecȝ型的指针
15.cȝ静态成员被当做该类cd的全局对象, 对于非静态成? 每个cd象都有自q拯, 而静态数据成员对每个cȝ型只有一个拷? 静态数据成员只
有一? 该类cdҎ(gu)有对象共享访?/span>
16.同全局对象相比, 使用静态数据成员有两个优势:
静态数据成员没有进入程序的全局名字I间
可以实现信息隐藏, 静态成员可以是private成员, 而全局对象不能
17.静态数据成员的cd可以是其他所属类, 而非static数据成员只能被声明ؓ(f)该类的对象的指针或引?/span>
18.静态数据成员可以被作ؓ(f)cL员函数的~省实参, 而非static成员不能
19.静态成员函数的声明除了在类体中的函数声明加上关键字static, 以及(qing)不能声明为const或volatile之外, 与非静态成员函数相? 出现在类体外的函?/span>
定义不能指定关键字static
20.静态成员没有this指针
21.cL员的指针必须L通过特定的对象或指向该类cd的对象的指针来访?/span>
针对cd象和引用?*
针对指向cd象的指针?>*
22.定义一个成员函数指针需要制定函数返回类? 参数表和c?
int (CTest::*)();
int (CTest::*pmf)() = &CTest::test;
pmf = &CTest::test2;
23.静态类成员属于该类的全局对象和函?/span>
24.联合:一U节省空间的c?/span>
使用union是危险的, 通过一个不适当的数据成员以为的获取到当前存储在union中的值]
25.c++标准库提供了一个bitsetcL? 它可以辅助操作位的集? 在可能的情况? 应尽可能使用它来取代位域
26.一个类可以在另一个类中定? q样的类被称为嵌套类(nested class)
嵌套cL其外围类的一个成?/span>
27.cM可以定义在函C? q样的类被称为局部类(local class)
局部类的成员函数必被定义在类定义? q就把局部类的成员函数的复杂性限制在几行代码?/span>
对象?br />5.catch-all
try {
....
}
catch(...) {} //catch-all格式
6.catch子句被检查的序与它们在try块之后出现的序相同, 一旦找C一个匹? 则后l的catch子句不再检?br />7.异常规范(exception specification)
void foo() throw(Object); //q种声明是异常规范
异常声明是函数接口的一部分
8.异常规范不允?dng)R被抛出的异常cd到异常规范制定的cd之间的{?
void foo() throw(string) {
....
throw "exception"; //不允总const char* 到string的{? 此时调用unexpected()
throw string("exception"); //可以
}
包含~译模式? 在每个模板被实例化的文g中包含函数模板的定义, q且往往把定义放在头文g? 向对内联函数左那?/span>
--~点: 函数模板?body)描述了实现细?/span>
分离~译模式? 函数模板声明攑֜头文件中, 函数模板定义攑֜cpp文g?/span>
//.h
template <typename Type> Type min(Type t1, Type t2);
//.cpp
export template <typename Type>
Type min(Type t1, Type t2) { /* ... */ }
//关键?export! 可导出的模板
//q不是所有的~译器都支持分离模式
查到文g之间的类型违? q些cdq例可能是程序严重错误的Ҏ(gu)
10.头文件ؓ(f)所向extern对象声明, 函数声明以及(qing)inline函数定义提供了一个集中的位置: q被UC声明的局部化(localization)
11.头文件提供了两个安全保证
保证所有文仉包含同一个全局对象或函数的同一份声?br />
如果需要修改声? 则只需要改变一个头文g
--只在本cpp用的全局函数, 该不该定义在头文仉?
12.局部对?local object)
自动对象(automatic object) --E序q行?br />
寄存器对?register object) --如果所选择的变量被频繁使用, 则寄存器变量可以提高函数的执行速度
局部静态对?local static object)
13.当一个自动变量的地址呗存储在一个生命期长与它的指针? 该指针被UCؓ(f)I?zhn)指?dangling pointer)
14.动态分配的对象被分配在E序的空闲存储区(free store)的可用内存池?br />
15.new表达式失败时, 通常?x)抛出bad_alloc异常
16.应用delete表达式失? 使内存无法返回空闲存储区, UC内存泄露(memory leak)
17.对用一内存应用了两ơdelete表达? 通常发生在两个指针指向同一个动态分配对象的时? q是一个很难跟t的问题
18.在对象被释放后读写该对象, q常怼(x)发生, 因ؓ(f)delete表达式应用的指针没有被设|ؓ(f)0
19.为帮助程序员更好地管理动态分配的内存, c++库提供了auto_ptrcȝ型的支持 --指针
20.auto_ptrcL板头文g<memory>
auto_ptr<int>pi(new int(1024));
//pi是局部智能指? 当pi生命期结束时? ?x)自动释放pi指向的堆I间
Z判断auto_ptr对象是否指向了一个对? 可以用操作get()q回auto_ptr对象内部的底层指?br />
if(p_auto_int.get() != 0 && *p_auto_int != 1024) { ... }
21.在某些情况下, 细节会(x)U聚成可怕的性能瓉, q些l节不应该烦扰那些试图ؓ(f)整个E序提供解决Ҏ(gu)的h, 但是q些l节是有l验的程序员应该考虑
?br />
22.定位new表达?br />
new表达式可以允许程序员要求对象创建在已经被分配好的内存中, q种形式的new表达式被UCؓ(f)定位new表达?placement new expression)
new (place_address) type -specifier
place_address必须是个指针
头文?lt;new>
byte *mem = new byte[4096]; //q个是自定义内存?
char *tmp = new(mem) char; //在内存池分配一个char来用?
delete [] mem;
定w)
4.capacity()操作 --求一个容器的定w
5.容器的长?--容器当前拥有元素的个?br />
6.size()操作 --求一个容器的长度
7.数据cd复? vector的效率就低
8.reserve()操作 --允许E序员将容器的容量设|成一个现实指定的?br />
9.q代?iterator) --提供了一U一般化的方? 寚w序或兌容器cd中的每个元素q行q箋讉K
10.每个容器cd都提供了一个begin()和一个end()成员函数
11.begin()q回一个iterator, 指向容器的第一个元?br />
12.end()q回一个iterator, 指向容器的末元素的下一个位|?br />
13.Ziteratorcd, 每个容器q定义了一个const iteratorcd, 对于遍历const容器是必需?br />
14.iterator术论算只适用于vector或deque, 而不适用与list, 因ؓ(f)ielist的元素在内存中不是连l存储的
15.string.find_first_of()查找与被搜烦字符串中L一个字W相匚w的第一ơ出? q返回它的烦引位|?br />
16.string.substr()生成string对象的字串的一个拷?br />
17.string.rfind()查找最后的指定字串出现的烦?br />
18.string.find_first_not_of()查找W一个不与要搜烦字符串的L字符相匹配的字符
19.string.find_last_of()查找字符串中?与搜索字W串L元素相匹?的最后一个字W?br />
20.string.find_last_not_of()查找字符串中?与搜索字W串L字符全不匚w"的最后一个字W?br />
21.string.erase(pos, num)操作L字符串中的指定串, pos表示位置, num表示L的长?br />
22.<locale>ctypec? {了标准c库函数的功能?qing)一l非成员函数
23.string.compare(pos, num, str); 比较pos位置的后面num个字W是否ؓ(f)str
24.string.insert(pos, newstring); pos表示要插入的位置, newstring表示要插入的字符?br />
25.string.assign(); 字符串拷?br />
26.string.append(); 字符串拼?br />
27.string.swap(); 交换两个字符?br />
28.string.at(); 对字W的下标索引操作, 有对索引D围检? 下标界时抛出out_of_range异常
try {
char ch = st.at(index);
} catch(std::out_of_range) { ... }
29.string.replace(pos, num, newstring); 用newstring代替pos后面num个字W子?br />
30.map 也叫兌数组(associative array) ?值对 key/value
键用来烦引map, 值用作存储和索的数据
map对象定义, 臛_要指明键和值的cd, ?
map<string, int> word_count;
31.map的数据录?br />
map<string, string> str_str;
str_str[string("one")] = string("1"); //q种效率比较?br />
str_str.insert(
map<string, string>::value_type("two", "2")
); //q种效率?br />
32.查找q获取map中的元素
最单的Ҏ(gu):
value = mapObj[key];
但这h个问? 如果不存在keyq个? mapObj׃(x)插入key? q把对应的valuegؓ(f)默认? q样得到的value是无效的
所? 应该q样?br />
if(mapObj.count(key))
value = mapObj[key];
或者这?
map<keyType, valueType>::iterator iter = mapObj.find(key);
if(iter != mapObj.end())
value = mapObj[key];
33.从map中删除元?br />
erase操作
mapObj.erase(key);
q有两种重蝲方式, 详见文档
mapObj.clear(); 清空map对象所有?br />
34.set对象插入元素
#include <set>
set<setType> setObj;
setObj.insert(key);
35.set对象查找元素
setObj.count(key); //1? 0没有
setObj.find(key); iter为setObj.end()表示没有
36.multiset和multimap允许要被存储的键出现多次
对于multiset和multimap的P代策略是联合使用findq回的iterator和countq回的?
count = mulsetObj.count();
multiset<type>::iterator iter;
iter = mulsetObj.find(key);
for(int i = 0; i < count; ++i, ++iter)
do_something(*iter);
另一U方法是使用equal_range()q回的iterator?br />
如果q个值存? 则第一个iterator指向该值的W一个实? 且第二个iterator指向q个值的最后一个实例的下一个位|?
switch(mulmapObj.count) {
case 0: break; //不存?br />
case 1: //只有一? 用普通的find操作
multimap<keyType, valueType>::iterator iter;
iter = mulmapObj.find(key);
do_something(*iter);
break;
default: //有许多项
typedef multimap<keyType, valueType>::iterator it;
pair<it, it>pos;
pos = mulmapObj.equal_range(key);
for(; pos.first != pos.second; pos.first++)
do_somethine(*pos.first);
}
//对应? 删除的话用mulmapObj.erase(pos.first, pos.second);
//不支持下标操作是讉Kmultimap元素的一个限?
mulmapObj[key]; //错误
37.栈容?stack container)支持的操?//头文?lt;stack>
empty()
size()
pop()
top()
push(item)
38.栈类型被UCؓ(f)容器适配?container adapter)
39.~省情况? 栈用容器cddeque实现, 改变q个~省值可以这?
stack<type, list<type>> stackObj; //Ҏ(gu)用容器类型list实现
//一般是定义一个指针栈
class CTest;
stack<CTest*> ctestStack;
40.标准库提供了两种风格的队? queue(队列), priority_queue(优先U队?
头文?<queue>
41.queue和priority_queue操作
empty()
size()
pos()
front() //只能用在一般队?br />
back() //只能用在一般队?br />
top() //只能用在优先U队?br />
push(item)