??xml version="1.0" encoding="utf-8" standalone="yes"?>色欲综合久久中文字幕网,精品综合久久久久久97超人,国产91色综合久久免费分享http://www.shnenglu.com/richardzeng/VC++ 斚w~程文章zh-cnWed, 07 May 2025 01:25:02 GMTWed, 07 May 2025 01:25:02 GMT60Windows GDI CDC 使用问题http://www.shnenglu.com/richardzeng/archive/2006/07/16/10112.htmlBeginning to ~程Beginning to ~程Sat, 15 Jul 2006 19:06:00 GMThttp://www.shnenglu.com/richardzeng/archive/2006/07/16/10112.htmlhttp://www.shnenglu.com/richardzeng/comments/10112.htmlhttp://www.shnenglu.com/richardzeng/archive/2006/07/16/10112.html#Feedback2http://www.shnenglu.com/richardzeng/comments/commentRss/10112.htmlhttp://www.shnenglu.com/richardzeng/services/trackbacks/10112.html最q在学习Hoops   的引擎(http://www.hoops3d.com )

模拟它的MVO架构Q不q没有原代码Q所以很难a
设计了一个交互绘囑֟本类Q?br />但是q有错误Q鼠标左键点M?br /> winGDI.cpp中出错?br />请大虾指教一二?br />我已l在q个问题上花了很多的心思?br />其中最重要的就是Painter抽象cȝ设计
他的子类QBufferDCl承CDC
而SGView包含Painter指针Q方便在SGView ::drawEntity调用?br />


SGObject - 对象的抽象类Q也是几何对象
SGModel- 负责对象理Q没有实现所有的功能Q准备用SceneTree来实?br />SGView - 负责昄SGModel中的数据Q关键的函数
void SGView::drawEntity(SGObject* pObj)
{
   pObj->draw(m_pPainter,this)
}

Painter - 装CDC的功?见代?br />
在CSGView创徏的时候创建Painter对象
很可能这里有问题Q!Q!Q?br />void CSGView::OnCreate(..)
{
     CDC* pDC = GetDC();
   Painter* painter = new QBufferDC(pDC);
   m_pSGView->setPainter(painter);
}


MFC 相关的Document/View架构
CSGDocument - 理SGModel

CSGView - 和SGView建立联系Qƈ负责把windows的消息发送给SGView
见原代码

SGActionManager - 负责工具的管?br />SGBaseAction - 工具的抽象基c?br />SGActionDrawLine - l制直线的工?br />


源代码连接:
http://www.shnenglu.com/Files/richardzeng/MVOTest.rar



Beginning to ~程 2006-07-16 03:06 发表评论
]]>
资源和资源管理类的设计问?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/05/27/7741.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Sat, 27 May 2006 14:19:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/05/27/7741.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/7741.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/05/27/7741.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/7741.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/7741.html</trackback:ping><description><![CDATA[ <p> <br />我要设计的应用程序其中的一个模块就是封?windows GDI中的ȝQ画LGDI object<br />把GDI object 再封装成resourceQ以实现多种样式多线条的ȝ及画刯?/p> <p>ȝQ画L资源l承resource<br />Z避免发生资源泄露和resource的管?br />设计ResourceManagerc,负责资源的创建,加蝲和卸载以及删?/p> <p>两个抽象c?Resource ?ResourceManager<br />两个具体c?ConcreateResource ?ConcreateResourceManager<br />分别z于上面的抽象c?/p> <p>以上设计是看?OGRE 游戏引擎的资源管理部分,<br />对它的资源管理类ResourceManager不是很理?/p> <p>resource z了pen,brush{类<br />pencd以来自文Ӟ也可以自己创建SubPen d到SubPenList?/p> <p>ResourceManager 负责创徏资源Resource<br />1. 如果我在抽象?ResourceManager 声明 createRes函数Qƈq回基类resource<br />势必会要强制转换Q然后在用到具体的Resource时候又要{换回?/p> <p>2. 如果我在具体c?ConcreateResourceManager 声明 createConcreateRes函数<br />那么q费了我应用设计模式设计这么多c?/p> <p> <br />// abstract class for resource<br />class Resource{<br />public:<br /> // standard constructor<br />  Resource(const string& name, const string& group)<br /> :mName(name),mGroup(group){}<br />  ~Resource(){}<br />protected:<br /> // prevent default construct<br />  Resource():mName(""),mGroup(""){}<br />  string mName;<br />  string mGroup;<br />  static unsigned long mHandle;<br />};</p> <p>// subclass of resource<br />// concreateResource such as PEN<br />class Pen:<br /> public Resource{<br /> Pen(const string& name, const string& group)<br />  :Resource(name,group){}<br />  ~Pen(){}<br /><br />  void loadfromFile(string& filename);<br /><br />// add into vector<br />  void addSubPen(SubPen* sub){<br />     mSubPenList.push_back(sub);<br />}<br />public:<br />typedef std::vector<SubPen> SubPenList;<br />SubPenList mSubPenList;</p> <p>};<br />class <br />// abstract class for resource manager<br />class ResourceManager{<br />public:<br />  ResourceManager(){}<br />  ~ResourceManager(){}<br />public:<br />// here , I cannot understand OGRE degsin<br />  Resource* createRes(const string& name,const string& group);<br /> // resource map <br /> typedef std::map<string,Resource*> ResourceMap;<br />   ResourceMap mResources;</p> <p>};</p> <p>// subclass ResourceManager<br />class ConcreateResourceManager<br /> :public ResourceManager<br />{<br /> ConcreateResourceManager(){}<br /> ~ConcreateResourceManager(){}</p> <p>      // how can design here!!<br />       Pen* createPen(const string& name,const string& group){}<br />}</p> <p> </p> <img src ="http://www.shnenglu.com/richardzeng/aggbug/7741.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-05-27 22:19 <a href="http://www.shnenglu.com/richardzeng/archive/2006/05/27/7741.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MFC 容器cd象的序列化问?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/05/15/7223.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Mon, 15 May 2006 14:14:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/05/15/7223.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/7223.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/05/15/7223.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/7223.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/7223.html</trackback:ping><description><![CDATA[ <p>设计一个程序实现如何保存一pd的SPenQ如下定义)对象到文Ӟ或者称为序列化SPen collection<br /><br />SPenCollection::Load?Save函数实现打开ȝ文gQ文件的内容是一pdSPen对象Q?br />// for example<br /> SPenCollection pc;<br /> pc.Load("C:\\1.pen");<br /><br />我不知道如何序列化容器类对象Q请大虾指教?br /><br /><br /><br />// SPen object<br />class SPen : public CObject<br />{<br /> DECLARE_SERIAL(SPen)<br />public:<br /> SPen();<br /> virtual ~SPen();</p> <p>public:<br /> int lineStyle;<br /> int lineWidth;<br /> COLORREF lineColor;<br />public:<br /> virtual void Serialize(CArchive& ar);<br />};<br /><br /><br />// SPen.cpp : 实现文g<br />//</p> <p>#include "stdafx.h"<br />#include "ArchiveTest.h"<br />#include "SPen.h"</p> <p> <br />// SPen<br />IMPLEMENT_SERIAL(SPen,CObject,1)</p> <p>SPen::SPen()<br />{<br /> lineStyle = PS_SOLID;<br /> lineWidth = 2;<br /> lineColor = RGB(255,0,0);<br />}</p> <p>SPen::~SPen()<br />{<br />}</p> <p> <br />// SPen 成员函数</p> <p>void SPen::Serialize(CArchive& ar)<br />{<br /> if (ar.IsStoring())<br /> { // storing code<br />  ar<<lineStyle;<br />  ar<<lineWidth;<br />  ar<<lineColor;<br /> }<br /> else<br /> { // loading code<br />  ar>>lineStyle;<br />  ar>>lineWidth;<br />  ar>>lineColor;<br /> }<br />}<br /><br /><br />///////////////////////////////////////<br />// 关键是要实现如何保存一pd的SPen对象<br />// load ?save函数实现打开ȝ文gQ文件的内容是一pdSPen对象Q?br />// for example<br />/** SPenCollection pc;<br />   pc.Load("C:\\1.pen");<br /> **/<br /><br />#pragma once</p> <p>// SPenCollection 命o目标</p> <p>#include "SPen.h"<br />#include <afxtempl.h></p> <p>class SPenCollection : public CObject<br />{<br /> DECLARE_SERIAL(SPenCollection)<br />public:<br /> SPenCollection();<br /> virtual ~SPenCollection();<br /><br /> void AddPen(SPen* pen);</p> <p> void Load(CString strFileName);<br /> void Save(CString strFileName);</p> <p>// CArray 不知道用得对不对Q请大虾指教<br /> CArray<SPen*,SPen*> pens;<br />};</p> <p> <br /> </p> <img src ="http://www.shnenglu.com/richardzeng/aggbug/7223.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-05-15 22:14 <a href="http://www.shnenglu.com/richardzeng/archive/2006/05/15/7223.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost serialize ?ostream 问题 http://www.shnenglu.com/richardzeng/archive/2006/05/15/7202.htmlBeginning to ~程Beginning to ~程Mon, 15 May 2006 09:26:00 GMThttp://www.shnenglu.com/richardzeng/archive/2006/05/15/7202.htmlhttp://www.shnenglu.com/richardzeng/comments/7202.htmlhttp://www.shnenglu.com/richardzeng/archive/2006/05/15/7202.html#Feedback1http://www.shnenglu.com/richardzeng/comments/commentRss/7202.htmlhttp://www.shnenglu.com/richardzeng/services/trackbacks/7202.html
下面是Boost serialization 中的demo例子
Z写了serialize 函数q写个ostream<<
阿,
我对ostream 不是很了解,
我的印象是iostream 是在控制台里输入输出?/div>
/////////////////////////////////////////////////////////////////////////////
class gps_position
{
    friend std::ostream & operator<<(std::ostream &os, const gps_position &gp);
    friend class boost::serialization::access;
    int degrees;
    int minutes;
    float seconds;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */){
        ar & degrees & minutes & seconds;
    }
public:
    // every serializable class needs a constructor
    gps_position(){};
    gps_position(int _d, int _m, float _s) :
        degrees(_d), minutes(_m), seconds(_s)
    {}
};
std::ostream & operator<<(std::ostream &os, const gps_position &gp)
{
    return os << ' ' << gp.degrees << (unsigned char)186 << gp.minutes << '\'' << gp.seconds << '"';
}


Beginning to ~程 2006-05-15 17:26 发表评论
]]>
fatal error LNK1104: 无法打开文g“libboost_serialization-vc80-mt-gd-1_33_1.lib?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/05/15/7169.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Mon, 15 May 2006 02:54:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/05/15/7169.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/7169.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/05/15/7169.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/7169.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/7169.html</trackback:ping><description><![CDATA[ 最q想试试boostQ下载了boost 1.33.1<br />我目前用的是VC++2005Q?br />首先~译bjam, 不过用boost 1.33.1 \tools \jam-src 下的build.bat不用又从sf上下载了<br />最新的bjam,然后~译bjam,倒是很简单很快就好生成bjam.exe<br /><br />然后把bjam的\径设|到path 环境变量?br />一切都q行正常?br /><br />我首先就~译了boost -serialization <br /><br />在命令行模式?br />cd <boost-serialization 目录><br />q行bjam "-sTOOLS=vc-8_0"<br /><br />~译完成后在boost 目录下生成了bin 目录C:\boost_1_33_1\bin\<br />我编译的serialization lib 文g在这?br />C:\boost_1_33_1\bin\boost\libs\serialization\build\boost_serialization.dll\vc-8_0\debug\threading-multiQ当然还有其它的lib,dll<br /><br />首先讄vc++包含文g目录C:\boost_1_33_1\<br />库文件设|在C:\boost_1_33_1\bin\boost\libs\serialization\build\boost_serialization.dll\vc-8_0\debug\threading-multiQ?br />Q这个肯定不好,N我需要一个lib文gp在这里加一个\径,因ؓ~译的lib文g太分散,没有集中,不知道copyCh否可?<br /><br />然后我copy boost serialization 中demo代码Q?br />~译demo.cppQ就提示 fatal error LNK1104: 无法打开文g“libboost_serialization-vc80-mt-gd-1_33_1.lib?br /><br />我想是不是lib文g的\径不寚wQ把要的libboost_serialization-vc80-mt-gd-1_33_1.lib 拯到C:\boost_1_33_1\libs<br />下还是不行,讄目依赖文g也不行,<br />到底在vc++2005 中怎么讄boost的环境阿<br /><img src ="http://www.shnenglu.com/richardzeng/aggbug/7169.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-05-15 10:54 <a href="http://www.shnenglu.com/richardzeng/archive/2006/05/15/7169.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>不能“this”指针从“const Vector3D”{换ؓ“Vector3D &" 错误http://www.shnenglu.com/richardzeng/archive/2006/05/10/6876.htmlBeginning to ~程Beginning to ~程Wed, 10 May 2006 06:42:00 GMThttp://www.shnenglu.com/richardzeng/archive/2006/05/10/6876.htmlhttp://www.shnenglu.com/richardzeng/comments/6876.htmlhttp://www.shnenglu.com/richardzeng/archive/2006/05/10/6876.html#Feedback2http://www.shnenglu.com/richardzeng/comments/commentRss/6876.htmlhttp://www.shnenglu.com/richardzeng/services/trackbacks/6876.html我在VS2005中编译Vector3Dcd?br />error C2662: “Vector3D::dotP? 不能“this”指针从“const Vector3D”{换ؓ“Vector3D &?br />
怎么h正呢Q这个类也是看到别hq样写的Q编译也没有错误?br />
#pragma once

#define M_PI 3.141
#include <math.h>

class Vector3D{
 Vector3D(){x=y=z=0.0;}
 Vector3D(double vx, double vy,double vz=0.0){
  x = vx;
  y = vy;
  z = vz;
 }
 
 double magnitude() const{
  return sqrt(x*x+y*y+z*z);
 }

 double dotP(const Vector3D& v1,const Vector3D& v2){
  return (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z);
 }

 // get the vector angle
 double angle() const{
  double ret = 0.0;
  double m = magnitude();

  if (m>1.0e-6) {

// 问题出在q里Q!Q!
// ==============================
   double dp = dotP(*this,Vector3D(1.0,0.0));
//==============================

   if (dp/m>=1.0) {
    ret = 0.0;
   }
   else if (dp/m<-1.0) {
    ret = M_PI;
   }
   else {
    ret = acos( dp / m);
   }
   if (y<0.0) {
    ret = 2*M_PI - ret;
   }
  }
  return ret;
 }


protected:
 double x;
 double y;
 double z;

};#pragma once

#define M_PI 3.141
#include <math.h>

class Vector3D{
 Vector3D(){x=y=z=0.0;}
 Vector3D(double vx, double vy,double vz=0.0){
  x = vx;
  y = vy;
  z = vz;
 }
 
 double magnitude() const{
  return sqrt(x*x+y*y+z*z);
 }

 double dotP(const Vector3D& v1,const Vector3D& v2){
  return (v1.x*v2.x+v1.y*v2.y+v1.z*v2.z);
 }

 // get the vector angle
 double angle() const{
  double ret = 0.0;
  double m = magnitude();

  if (m>1.0e-6) {
   double dp = dotP(*this,Vector3D(1.0,0.0));

   if (dp/m>=1.0) {
    ret = 0.0;
   }
   else if (dp/m<-1.0) {
    ret = M_PI;
   }
   else {
    ret = acos( dp / m);
   }
   if (y<0.0) {
    ret = 2*M_PI - ret;
   }
  }
  return ret;
 }


protected:
 double x;
 double y;
 double z;

};



Beginning to ~程 2006-05-10 14:42 发表评论
]]>
C++中Singleton的实现[zhuan]http://www.shnenglu.com/richardzeng/archive/2006/04/21/5999.htmlBeginning to ~程Beginning to ~程Fri, 21 Apr 2006 01:31:00 GMThttp://www.shnenglu.com/richardzeng/archive/2006/04/21/5999.htmlhttp://www.shnenglu.com/richardzeng/comments/5999.htmlhttp://www.shnenglu.com/richardzeng/archive/2006/04/21/5999.html#Feedback0http://www.shnenglu.com/richardzeng/comments/commentRss/5999.htmlhttp://www.shnenglu.com/richardzeng/services/trackbacks/5999.html
q些东西在网上都很多了,但是我觉得他们的使用都不W合我的要求Q所以自己动手丰衣食,写一个自p用的Q够用就好?/div>
#include <iostream>
 
using namespace std;
 
//单g模板c?/div>
template<typename T> class Singleton
{
protected:
 
  static T* m_Instance;
 
  Singleton(){}
  virtual~Singleton(){}
 
public:
 
  //实例的获?/div>
  static T* Instance()
  {
    if(m_Instance==0)
      m_Instance=new T;
 
    return m_Instance;
  }
 
  //单gcȝ释放
  virtual void Release()
  {
    if(m_Instance!=0)
    {
      delete m_Instance;
      m_Instance=0;
    }
  }
};
 
//单g模板试c?/div>
class Test:public Singleton<Test>
{
  friend class Singleton<Test>; //声明为友员,不然会出?/div>
protected:
  Test()
  {
    a=b=c=0;
  }
  virtual ~Test(){}
 
public :
 
  int a;
  int b;
  int c;
};
 
//初始化静态成员。。?/div>
template<> Test*Singleton<Test>::m_Instance=0;
 
 
//以下为测试代?/div>
void main()
{
  Test*t=Test::Instance();
 
  t->a=5;
  t->b=25;
  t->c=35;
  cout<<"t: a="<<t->a<<" b="<<t->b<<" c="<<t->c<<endl;
 
  Test*t2;
  t2=Test::Instance();
  cout<<"t2 a="<<t2->a<<" b="<<t2->b<<" c="<<t2->c<<endl;
 
  t2->Release();
}


Beginning to ~程 2006-04-21 09:31 发表评论
]]>
EffectiveC++2ed 关于函数q回对象Q引用还是指?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Fri, 24 Mar 2006 07:51:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/4540.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/4540.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/4540.html</trackback:ping><description><![CDATA[ <h2> <font size="3">我看到EffectiveC++2ed中函数返回对象中的说明感觉以后再也不惌q回M东西啦。比较怕?/font> </h2> <p>但是有的时候不q回M东西是不行的ѝ?/p> <p>q回引用Q返回指针,q回对象到底怎么写?Q?br /><br />—————————————————————————————?br />下面是IQ中的内?/p> <h2>条款23: 必须q回一个对象时不要试图q回一个引?/h2> <p> </p> <p>据说爱因斯坦曾提q样的徏议:可能地让事情简单,但不要过于简单。在c++语言中相似的说法应该是:可能地使程序高效,但不要过于高效?/p> <p>一旦程序员抓住了“传值”在效率上的把柄Q参见条?2Q,他们会变得十分极端,恨不得挖出每一个隐藏在E序中的传值操作。岂不知Q在他们不懈地追求纯_的“传引用”的q程中,他们会不可避免地犯另一个严重的错误Q传递一个ƈ不存在的对象的引用。这׃是好事了?/p> <p>看一个表C有理数的类Q其中包含一个友元函敎ͼ用于两个有理数相乘:</p> <p>class rational {<br />public:<br />  rational(int numerator = 0, int denominator = 1);</p> <p>  ...</p> <p>private:<br />  int n, d;              // 分子和分?/p> <p>friend<br />  const rational                      // 参见条款21Qؓ什?br />    operator*(const rational& lhs,    // q回值是const<br />              const rational& rhs)     <br />};</p> <p>inline const rational operator*(const rational& lhs,<br />                                const rational& rhs)<br />{<br />  return rational(lhs.n * rhs.n, lhs.d * rhs.d);<br />}</p> <p>很明显,q个版本的operator*是通过传D回对象结果,如果不去考虑对象构造和析构时的开销Q你是在逃避作ؓ一个程序员的责仅R另外一件很明显的事实是Q除非确实有必要Q否则谁都不愿意承担q样一个时对象的开销。那么,问题归l于Q确实有必要吗?</p> <p>{案是,如果能返回一个引用,当然没有必要。但误住,引用只是一个名字,一个其它某个已l存在的对象的名字。无Z时看C个引用的声明Q就要立即问自己Q它的另一个名字是什么呢Q因为它必然q有另外一个什么名字(见条ƾm1Q。拿operator*来说Q如果函数要q回一个引用,那它q回的必L其它某个已经存在的rational对象的引用,q个对象包含了两个对象相乘的l果?/p> <p>但,期望在调用operator*之前有这样一个对象存在是没道理的。也是_如果有下面的代码Q?/p> <p>rational a(1, 2);                // a = 1/2<br />rational b(3, 5);                // b = 3/5<br />rational c = a * b;              // c ?3/10</p> <p>期望已经存在一个gؓ3/10的有理数是不现实的。如果operator* 一定要q回q样一个数的引用,必自己创个数的对象?/p> <p>一个函数只能有两种Ҏ(gu)创徏一个新对象Q在堆栈里或在堆上。在堆栈里创建对象时伴随着一个局部变量的定义Q采用这U方法,pq样写operator*Q?/p> <p>// 写此函数的第一个错误方?br />inline const rational& operator*(const rational& lhs,<br />                                 const rational& rhs)<br />{<br />  rational result(lhs.n * rhs.n, lhs.d * rhs.d);<br />  return result;<br />}</p> <p>q个Ҏ(gu)应该被否冻I因ؓ我们的目标是避免构造函数被调用Q但result必须要象其它对象一栯构造。另外,q个函数q有另外一个更严重的问题,它返回的是一个局部对象的引用Q关于这个错误,条款31q行了深入的讨论?/p> <p>那么Q在堆上创徏一个对象然后返回它的引用呢Q基于堆的对象是通过使用new产生的,所以应该这样写operator*Q?/p> <p>// 写此函数的第二个错误Ҏ(gu)<br />inline const rational& operator*(const rational& lhs,<br />                                 const rational& rhs)<br />{<br />  rational *result =<br />    new rational(lhs.n * rhs.n, lhs.d * rhs.d);<br />  return *result;<br />}</p> <p>首先Q你q是得负担构造函数调用的开销Q因为new分配的内存是通过调用一个适当的构造函数来初始化的Q见条款5和m8Q。另外,q有一个问题:谁将负责用delete来删除掉new生成的对象呢Q?/p> <p>实际上,q绝Ҏ(gu)一个内存泄漏。即使可以说服operator*的调用者去取函数返回值地址Q然后用deleted除它Q绝对不可能——条?1展示了这L代码会是什么样的)Q但一些复杂的表达式会产生没有名字的时|E序员是不可能得到的。例如:</p> <p>rational w, x, y, z;</p> <p>w = x * y * z;</p> <p>两个对operator*的调用都产生了没有名字的临时|E序员无法看刎ͼ因而无法删除。(再次参见条款31Q?/p> <p>也许Q你会想你比一般的熊——或一般的E序员——要聪明Q也许,你注意到在堆栈和堆上创徏对象的方法避免不了对构造函数的调用Q也许,你想起了我们最初的目标是ؓ了避免这U对构造函数的调用Q也许,你有个办法可以只用一个构造函数来搞掂一切;也许Q你的眼前出Cq样一D代码:operator*q回一个“在函数内部定义的静态rational对象”的引用Q?/p> <p>// 写此函数的第三个错误Ҏ(gu)<br />inline const rational& operator*(const rational& lhs,<br />                                 const rational& rhs)<br />{<br />  static rational result;      // 要作ؓ引用q回?br />                               // 静态对?/p> <p>  lhs和rhs 怹Q结果放qresultQ?/p> <p>  return result;<br />}</p> <p>q个Ҏ(gu)看v来好象有戏,虽然在实际实C面的伪代码时你会发现Q不调用一个rational构造函数是不可能给出result的正值的Q而避免这L调用正是我们要谈论的主题。就你实现了上面的伪代码,但,你再聪明也不能最l挽救这个不q的设计?/p> <p>想知道ؓ什么,看看下面q段写得很合理的用户代码Q?/p> <p>bool operator==(const rational& lhs,      // rationals的operator==<br />                const rational& rhs);     // </p> <p>rational a, b, c, d;</p> <p>...</p> <p>if ((a * b) == (c * d)) {</p> <p>  处理相等的情?</p> <p>} else {</p> <p>  处理不相{的情况;</p> <p>}</p> <p>看出来了吗?((a*b) == (c*d)) 会永qؓtrueQ不aQbQc和d是什么|</p> <p>用等L函数形式重写上面的相{判断语句就很容易明白发生这一可恶行ؓ的原因了Q?/p> <p>if (operator==(operator*(a, b), operator*(c, d)))</p> <p>注意当operator==被调用时QL两个operator*刚被调用Q每个调用返回operator*内部的静态rational对象的引用。于是,上面的语句实际上是请求operator==对“operator*内部的静态rational对象的值”和“operator*内部的静态rational对象的值”进行比较,q样的比较不相等才怪呢Q?/p> <p>q运的话Q我以上的说明应该以说服你Q想“在象operator*q样的函数里q回一个引用”实际上是在费旉。但我没q稚C怿q运M光自己。一些h——你们知道这些h是指谁——此M在想Q“唔Q上面那个方法,如果一个静态变量不够用Q也许可以用一个静态数l……?/p> <p>请就此打住!我们Nq没受够吗?</p> <p>我不能让自己写一D늤例代码来太高q个设计Q因为即使只抱有上面q种x都以o人感到羞愧。首先,你必选择一个nQ指定数l的大小。如果n太小Q就会没地方储存函数q回|q和我们前面否定的那个“采用单个静态变量的设计”相比没有什么改q。如果n太大Q就会降低程序的性能Q因为函数第一ơ被调用时数l中每个对象都要被创建。这会带来n个构造函数和n个析构函数的开销Q即使这个函数只被调用一ơ。如果说"optimization"Q最优化Q是指提高Y件的性能的过E, 那么现在q种做法直可以称?pessimization"Q最差化Q。最后,x怎么把需要的值放到数l的对象中以及需要多大的开销Q在对象间传值的最直接的方法是通过赋|但赋值的开销又有多大呢?一般来_它相当于调用一个析构函敎ͼ摧毁旧|再加上调用一个构造函敎ͼ拯新|。但我们现在的目标正是ؓ了避免构造和析构的开销啊!面对现实吧:q个Ҏ(gu)也绝对不能选用?/p> <p>所以,写一个必返回一个新对象的函数的正确Ҏ(gu)是让这个函数返回一个新对象。对于rational的operator*来说Q这意味着要不是下面的代码(是最初看到的那段代码Q,要不是本质上和它等L代码Q?/p> <p>inline const rational operator*(const rational& lhs,<br />                                const rational& rhs)<br />{<br />  return rational(lhs.n * rhs.n, lhs.d * rhs.d);<br />}</p> <p>的确Q这会导致“operator*的返回值构造和析构时带来的开销”,但归根结底它只是用小的代h来正的E序q行行ؓ而已。况且,你所担心的开销q有可能永远不会出现Q和所有程序设计语a一Pc++允许~译器的设计者采用一些优化措施来提高所生成的代码的性能Q所以,在有些场合,operator*的返回g被安全地除去Q见条款m20Q。当~译器采用了q种优化Ӟ当前大部分编译器q么做)Q程序和以前一Ll工作,只不q是q行速度比你预计的要快而已?/p> <p>以上讨论可以归结为:当需要在q回引用和返回对象间做决定时Q你的职责是选择可以完成正确功能的那个。至于怎么让这个选择所产生的代价尽可能的小Q那是编译器的生产商L的事?/p> <img src ="http://www.shnenglu.com/richardzeng/aggbug/4540.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-03-24 15:51 <a href="http://www.shnenglu.com/richardzeng/archive/2006/03/24/4540.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Doxygen 源代码文档自动生成器的用笔?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Thu, 23 Mar 2006 14:32:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/4508.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/4508.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/4508.html</trackback:ping><description><![CDATA[     摘要: ? google 上搜了很久的关于 Doxygen 使用Ҏ(gu)的咚咚,只不q都是英文,而且都很多的规则。实际上大家只需要告诉基本的规则可以。下面是我对 Doxygen 的摸?   首先熟知 Do...  <a href='http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html'>阅读全文</a><img src ="http://www.shnenglu.com/richardzeng/aggbug/4508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-03-23 22:32 <a href="http://www.shnenglu.com/richardzeng/archive/2006/03/23/4508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>查错Q下面的E序~译没问题,Z么运行会出错?/title><link>http://www.shnenglu.com/richardzeng/archive/2006/03/20/4389.html</link><dc:creator>Beginning to ~程</dc:creator><author>Beginning to ~程</author><pubDate>Mon, 20 Mar 2006 13:32:00 GMT</pubDate><guid>http://www.shnenglu.com/richardzeng/archive/2006/03/20/4389.html</guid><wfw:comment>http://www.shnenglu.com/richardzeng/comments/4389.html</wfw:comment><comments>http://www.shnenglu.com/richardzeng/archive/2006/03/20/4389.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.shnenglu.com/richardzeng/comments/commentRss/4389.html</wfw:commentRss><trackback:ping>http://www.shnenglu.com/richardzeng/services/trackbacks/4389.html</trackback:ping><description><![CDATA[ <p>最q在看吉林大学的CE序设计的课Ӟ有一章讲到这个函数动手写了一下?br /><br />题目Q?br />~写一个Insert函数实现在字W串s中的Wi个位|插入字W串s1Q?br />在VC++2005中编译这D늨序没有Q何的Error和warning但是q行׃错误Q不知道Z么阿Q请高手指点一二?br /><br />#include "stdafx.h"</p> <p>#include <iostream><br />using namespace std;</p> <p>void Insert(char *s, char *s1, int i)<br />{<br /> char *p,*q;<br /> p = s + strlen(s); // p 指向s的末?1<br /> q = p + strlen(s1); //q 指向新构造的字符串的\0 <br /> *q = '\0';</p> <p> // <br /> for(p--,q--;p>=s+i-1;)<br /> {<br />  *(p--) = *(q--);<br /> }</p> <p> //<br /> for(p=s+i-1;*s1;)<br /> {<br />  *(p++) = *(s1++);<br /> }<br />}<br /><br /><br />int _tmain(int argc, _TCHAR* argv[])<br />{</p> <p> char *s = "Student";<br /> char *s1 = "Teacher";</p> <p> Insert(s,s1,3);<br /><br />// 期待的输出是StuTeacherdent;<br /> cout<<s;</p> <p> <br /> return 0;<br />}<br /><br /><br />// q有我如果把insert函数Ҏ(gu)下面的应该也是可以的?br /></p> <p>void Insert2(char *s, char *s1, int i)<br />{<br /> char *p,*q;<br /> p = s + strlen(s); // p 指向s的末?1<br /> q = p + strlen(s1); //q 指向新构造的字符串的\0 <br /> *q = '\0';</p> <p> // <br /> for(p--,q--;p>=s+i-1;)<br /> {<br />  *p-- = *q--;<br /> }</p> <p> //<br /> for(p=s+i-1;*s1;)<br /> {<br />  *p++ = *s1++;<br /> }<br />}<br /></p> <img src ="http://www.shnenglu.com/richardzeng/aggbug/4389.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.shnenglu.com/richardzeng/" target="_blank">Beginning to ~程</a> 2006-03-20 21:32 <a href="http://www.shnenglu.com/richardzeng/archive/2006/03/20/4389.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <p>лǵվܻԴȤ</p> <a href="http://www.shnenglu.com/" title="精品视频久久久久">精品视频久久久久</a> <div class="friend-links"> </div> </div> </footer> <a href="http://www.u5qe.cn" target="_blank">Ļ˾Ʒþò</a>| <a href="http://www.hrwp.net.cn" target="_blank">Ʒþþþ</a>| <a href="http://www.40theft.cn" target="_blank">þٸ۲AV</a>| <a href="http://www.sehinix.cn" target="_blank">99þ99þþþƷ </a>| <a href="http://www.qqschool.cn" target="_blank">ھƷþþþþþþõӰ </a>| <a href="http://www.qilehu.cn" target="_blank">ŷ龫Ʒþþþþþ</a>| <a href="http://www.3ponline.com.cn" target="_blank">vavavaþ</a>| <a href="http://www.h7629.cn" target="_blank">ɫۺϾþþþĻ</a>| <a href="http://www.ihxc.cn" target="_blank">þþþþ</a>| <a href="http://www.168yetibizhi.cn" target="_blank">ۺϾþþƷ</a>| <a href="http://www.fqvb.cn" target="_blank">ݺɫۺվþþþþþ </a>| <a href="http://www.yes365cc.cn" target="_blank">þþþþþþþþѾƷ </a>| <a href="http://www.58city.cn" target="_blank">ƷƵþþ</a>| <a href="http://www.12530downs.com.cn" target="_blank">˾Ʒþ</a>| <a href="http://www.bekin.com.cn" target="_blank">ձѾþþþþþվ</a>| <a href="http://www.d13722.cn" target="_blank">Ʒһþù</a>| <a href="http://www.k7yg835v.cn" target="_blank">þ99Ʒþþþþò</a>| <a href="http://www.xp5hb9.cn" target="_blank">97þþƷƷ</a>| <a href="http://www.hxinfocom.cn" target="_blank">һһþaþþƷۺ鶹</a>| <a href="http://www.spinpizza.cn" target="_blank">97þþƷһ</a>| <a href="http://www.hyattzhuzhou.cn" target="_blank">ƷþþĻ</a>| <a href="http://www.huoguopot.cn" target="_blank">þҹۺϾþ</a>| <a href="http://www.caster.org.cn" target="_blank">þ99ëƬѹۿ</a>| <a href="http://www.shawcai.cn" target="_blank">ѾþþƷѾѾ</a>| <a href="http://www.dgzcwdlaw.cn" target="_blank">鶹AV뾫Ʒþ</a>| <a href="http://www.fylmbd.cn" target="_blank">ƷŮþøվ</a>| <a href="http://www.mengdie.net.cn" target="_blank">һþaþþƷۺҹҹ</a>| <a href="http://www.czb668.cn" target="_blank">þþþþþ91Ʒѹۿ </a>| <a href="http://www.77ns.cn" target="_blank">þþƷ鶹ҹҹ</a>| <a href="http://www.kunzuo.cn" target="_blank">ҹƷþ2021</a>| <a href="http://www.cqhydpqi.cn" target="_blank">þֹۺ޾Ʒ</a>| <a href="http://www.zqyipin.cn" target="_blank">ɫ8ŷ˾þۺϵ</a>| <a href="http://www.gzxwlt.cn" target="_blank">þ99Ʒ鶹</a>| <a href="http://www.ruixianscyz.cn" target="_blank">þþAVɫۺ</a>| <a href="http://www.mtsjnlaliji-syj.cn" target="_blank">þֹۺ޾Ʒ</a>| <a href="http://www.ebankon.com.cn" target="_blank">޾Ʒþþþþ</a>| <a href="http://www.hthotel.com.cn" target="_blank">þһٸ</a>| <a href="http://www.job158.cn" target="_blank">þۺϳ</a>| <a href="http://www.r7c1.cn" target="_blank">޾þһ </a>| <a href="http://www.pnpxnc.cn" target="_blank">þþ޾Ʒ</a>| <a href="http://www.gebendongxi.cn" target="_blank">þseֻоƷ</a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>