A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://www.stroustrup.com/bstechfaq.htm below:

  C++ Style and Technique FAQ £¨ÖÐÎİ棩

Bjarne Stroustrup Öø£¬ ×ÏÔÆÓ¢ Òë

[×¢: ±¾·Ã̸¼֮ÒëÎľ­Stroustrup²©Ê¿ÊÚȨ¡£ÈçÒª×ªÔØ£¬ÇëºÍÎÒÁªÏµ£º zmelody@sohu.com ]   Q: Õâ¸ö¼òµ¥µÄ³ÌÐò¡­¡­ÎÒÈçºÎ°ÑËü¸ã¶¨£¿

A: ³£³£ÓÐÈËÎÊÎÒһЩ¼òµ¥µÄ³ÌÐò¸ÃÈçºÎд£¬ÕâÔÚѧÆÚÖ®³õʱÓÈÉõ¡£Ò»¸öµäÐ͵ÄÎÊÌâÊÇ£ºÈçºÎ¶ÁÈëһЩÊý×Ö£¬×öЩ´¦Àí£¨±ÈÈçÊýѧÔËË㣩£¬È»ºóÊä³ö¡­¡­ºÃ°ÉºÃ°É£¬ÕâÀïÎÒ¸ø³öÒ»¸ö¡°Í¨ÓÃʾ·¶³ÌÐò¡±£º

	#include<iostream>
	#include<vector>
	#include<algorithm>
	using namespace std;

	int main()
	{
		vector<double> v;

		double d;
		while(cin>>d) v.push_back(d);	// read elements
		if (!cin.eof()) {		// check if input failed
			cerr << "format error\n";
			return 1;	// error return
		}

		cout << "read " << v.size() << " elements\n";

		reverse(v.begin(),v.end());
		cout << "elements in reverse order:\n";
		for (int i = 0; i<v.size(); ++i) cout << v[i] << '\n';

		return 0; // success return
	}

³ÌÐòºÜ¼òµ¥£¬Êǰɡ£ÕâÀïÊǶÔËüµÄһЩ¡°¹Û²ì±¨¸æ¡±£º

¡¶The C++ Programming Language ¡·µÚÈý°æÖйØÓÚ±ê×¼¿âµÄÕ½ÚÀïÓиü¶à¸üÏêϸÀý×Ó£¬Äã¿ÉÒÔͨ¹ýËüÃÇѧ»áÈçºÎʹÓñê×¼¿âÀ´¡°ÇáËɸ㶨¼òµ¥ÈÎÎñ¡±¡£

Q: ΪºÎÎÒ±àÒëÒ»¸ö³ÌÐòÒª»¨ÄÇô¶àʱ¼ä£¿

A: Ò²ÐíÊÇÄãµÄ±àÒëÆ÷Óе㲻̫¶ÔÍ·¡ª¡ªËüÊDz»ÊÇÄê¼ÍÌ«´óÁË£¬»òÕßûÓа²×°ÕýÈ·£¿Ò²¿ÉÄÜÄãµÄµçÄԸýø²©Îï¹ÝÁË¡­¡­¶ÔÓÚÕâÑùµÄÎÊÌâÎÒ¿ÉÕæÊǰ®ÄªÄÜÖúÁË¡£

²»¹ý£¬Ò²ÓпÉÄÜÔ­ÒòÔÚÓÚÄãµÄ³ÌÐò¡ª¡ª¿´¿´ÄãµÄ³ÌÐòÉè¼Æ»¹Äܲ»ÄܸĽø£¿±àÒëÆ÷ÊDz»ÊÇΪÁË˳Àû²ú³öÕýÈ·µÄ¶þ½øÖÆÂë¶ø²»µÃ²»³Ô½ø³É°Ù¸öÍ·Îļþ¡¢¼¸ÍòÐеÄÔ´´úÂ룿ԭÔòÉÏ£¬Ö»Òª¶ÔÔ´ÂëÊʵ±ÓÅ»¯Ò»Ï£¬±àÒ뻺ÂýµÄÎÊÌâÓ¦¸Ã¿ÉÒÔ½â¾ö¡£Èç¹ûÖ¢½áÔÚÓÚÄãµÄÀà¿â¹©Ó¦ÉÌ£¬ÄÇôÄã´ó¸Å³ýÁË¡°»»Ò»¼ÒÀà¿â¹©Ó¦ÉÌ¡±Íâȷʵûʲô¿É×öµÄÁË£»µ«Èç¹ûÎÊÌâÔÚÓÚÄã×Ô¼ºµÄ´úÂ룬ÄÇôÍêÈ«¿ÉÒÔͨ¹ýÖØ¹¹£¨refactoring£©À´ÈÃÄãµÄ´úÂë¸üΪ½á¹¹»¯£¬´Ó¶øÊ¹Ô´ÂëÒ»µ©Óиü¸ÄʱÐèÖØ±àÒëµÄ´úÂëÁ¿×îС¡£ÕâÑùµÄ´úÂëÍùÍùÊǸüºÃµÄÉè¼Æ£ºÒòΪËüµÄźºÏ³Ì¶È½ÏµÍ£¬¿Éά»¤ÐԽϼѡ£

ÎÒÃÇÀ´¿´Ò»¸öOOPµÄ¾­µäÀý×Ó£º

	class Shape {
	public:		// interface to users of Shapes
		virtual void draw() const;
		virtual void rotate(int degrees);
		// ...
	protected:	// common data (for implementers of Shapes)
		Point center;
		Color col;
		// ...
	};

	class Circle : public Shape {
	public:	
		void draw() const;
		void rotate(int) { }
		// ...
	protected:
		int radius;
		// ...
	};

	class Triangle : public Shape {
	public:	
		void draw() const;
		void rotate(int);
		// ...
	protected:
		Point a, b, c;
		// ...
	};	

ÉÏÊö´úÂëչʾµÄÉè¼ÆÀíÄîÊÇ£ºÈÃÓû§Í¨¹ýShapeµÄ¹«¹²½çÃæÀ´´¦Àí¡°¸÷ÖÖÐÎ×´¡±£»¶øShapeµÄ±£»¤³ÉÔ±ÌṩÁ˸÷¼Ì³ÐÀࣨ±ÈÈçCircle£¬Triangle£©¹²Í¬ÐèÒªµÄ¹¦ÄÜ¡£Ò²¾ÍÊÇ˵£º½«¸÷ÖÖÐÎ×´£¨shapes£©µÄ¹«¹²ÒòËØ»®¹éµ½»ùÀàShapeÖÐÈ¥¡£ÕâÖÖÀíÄî¿´À´ºÜºÏÀí£¬²»¹ýÎÒÒªÌáÇëÄã×¢Ò⣺

ËùÒÔ£¬ÔÚ»ùÀàÖзÅһЩ¡°¶ÔÓڼ̳ÐÀà֮ʵ×÷ÓаïÖú¡±µÄ¹¦ÄÜ»òÐíÊdzöÓÚºÃÒ⣬µ«ÊµÔòÊÇÂé·³µÄԴȪ¡£Óû§µÄÒªÇóÊǶà±äµÄ£¬ËùÒÔʵ×÷´úÂëÒ²ÊǶà±äµÄ¡£½«¶à±äµÄ´úÂë·ÅÔÚÐí¶à¼Ì³ÐÀà¶¼ÒªÓõ½µÄ»ùÀàÖ®ÖУ¬ÄÇô±ä»¯¿É¾Í²»ÊǾֲ¿µÄÁË£¬Õâ»áÔì³ÉÈ«¾ÖÓ°ÏìµÄ£¡¾ßÌå¶øÑÔ¾ÍÊÇ£º»ùÀàËùÒÐÀµµÄÒ»¸öÍ·Îļþ±ä¶¯ÁË£¬ÄÇôËùÓм̳ÐÀàËùÔÚµÄÎļþ¶¼ÐèÖØÐ±àÒë¡£

ÕâÑù·ÖÎö¹ýºó£¬½â¾öÖ®µÀ¾ÍÏÔ¶øÒ×¼ûÁË£º½ö½ö°Ñ»ùÀàÓÃ×÷Ϊ³éÏóµÄ¹«¹²½çÃæ£¬¶ø½«¡°¶Ô¼Ì³ÐÀàÓÐÓá±µÄʵ×÷¹¦ÄÜÒÆ³ö¡£

	class Shape {
	public:		// interface to users of Shapes
		virtual void draw() const = 0;
		virtual void rotate(int degrees) = 0;
		virtual Point center() const = 0;
		// ...

		// no data
	};

	class Circle : public Shape {
	public:	
		void draw() const;
		void rotate(int) { }
		Point center() const { return center; }
		// ...
	protected:
		Point cent;
		Color col;
		int radius;
		// ...
	};

	class Triangle : public Shape {
	public:	
		void draw() const;
		void rotate(int);
		Point center() const;
		// ...
	protected:
		Color col;
		Point a, b, c;
		// ...
	};	

ÕâÑù£¬¼Ì³ÐÀàµÄ±ä»¯¾Í±»¹ÂÁ¢ÆðÀ´ÁË¡£Óɱ仯´øÀ´µÄÖØ±àÒëʱ¼ä¿ÉÒÔ¼«ÎªÏÔÖøµØËõ¶Ì¡£

µ«ÊÇ£¬Èç¹ûȷʵÓÐһЩ¹¦ÄÜÊÇÒª±»ËùÓм̳ÐÀࣨ»òÕß½ö½ö¼¸¸ö¼Ì³ÐÀࣩ¹²ÏíµÄ£¬ÓÖ²»ÏëÔÚÿ¸ö¼Ì³ÐÀàÖÐÖØ¸´ÕâЩ´úÂ룬ÄÇÔõô°ì£¿Ò²ºÃ°ì£º°ÑÕâЩ¹¦ÄÜ·â×°³ÉÒ»¸öÀ࣬Èç¹û¼Ì³ÐÀàÒªÓõ½ÕâЩ¹¦ÄÜ£¬¾ÍÈÃËüÔټ̳ÐÕâ¸öÀࣺ

	class Shape {
	public:		// interface to users of Shapes
		virtual void draw() const = 0;
		virtual void rotate(int degrees) = 0;
		virtual Point center() const = 0;
		// ...

		// no data
	};

	struct Common {
		Color col;
		// ...
	};
		
	class Circle : public Shape, protected Common {
	public:	
		void draw() const;
		void rotate(int) { }
		Point center() const { return center; }
		// ...
	protected:
		Point cent;
		int radius;
	};

	class Triangle : public Shape, protected Common {
	public:	
		void draw() const;
		void rotate(int);
		Point center() const;
		// ...
	protected:
		Point a, b, c;
	};	

[Òë×¢£ºÕâÀï×÷ÕßµÄ˼·¾ÍÊǹÂÁ¢±ä»¯£¬¼õÉÙñîºÏ¡£´ÓÕâ¸öÀý×ÓÖжÁÕß¿ÉÒÔѧµ½Ò»µãRefactoringµÄÈëÃÅ֪ʶ :O) ]

Q: ΪºÎ¿ÕÀàµÄ´óС²»ÊÇÁ㣿

A: ΪÁËÈ·±£Á½¸ö²»Í¬¶ÔÏóµÄµØÖ·²»Í¬£¬±ØÐëÈç´Ë¡£Ò²ÕýÒòΪÈç´Ë£¬new·µ»ØµÄÖ¸Õë×ÜÊÇÖ¸Ïò²»Í¬µÄµ¥¸ö¶ÔÏó¡£ÎÒÃÇ»¹ÊÇÀ´¿´´úÂë°É£º

	class Empty { };

	void f()
	{
		Empty a, b;
		if (&a == &b) cout << "impossible: report error to compiler supplier";

		Empty* p1 = new Empty;
		Empty* p2 = new Empty;
		if (p1 == p2) cout << "impossible: report error to compiler supplier";
	}	

ÁíÍ⣬C++ÖÐÓÐÒ»ÌõÓÐȤµÄ¹æÔò¡ª¡ª¿Õ»ùÀಢ²»ÐèÒªÁíÍâÒ»¸ö×Ö½ÚÀ´±íʾ£º

	struct X : Empty {
		int a;
		// ...
	};

	void f(X* p)
	{
		void* p1 = p;
		void* p2 = &p->a;
		if (p1 == p2) cout << "nice: good optimizer";
	}

Èç¹ûÉÏÊö´úÂëÖÐp1ºÍp2ÏàµÈ£¬ÄÇô˵Ã÷±àÒëÆ÷×÷ÁËÓÅ»¯¡£ÕâÑùµÄÓÅ»¯Êǰ²È«µÄ£¬¶øÇҷdz£ÓÐÓá£ËüÔÊÐí³ÌÐòÔ±ÓÿÕÀàÀ´±íʾ·Ç³£¼òµ¥µÄ¸ÅÄ¶ø²»ÐèΪ´Ë¸¶³ö¶îÍâµÄ£¨¿Õ¼ä£©´ú¼Û¡£Ò»Ð©ÏÖ´ú±àÒëÆ÷ÌṩÁËÕâÖÖ¡°Ðé»ùÀàÓÅ»¯¡±¹¦ÄÜ¡£

Q: ΪʲôÎÒ±ØÐë°ÑÊý¾Ý·Åµ½ÀàµÄÉùÃ÷Ö®ÖУ¿ A: ûÈËÇ¿ÆÈÄãÕâô×ö¡£Èç¹ûÄ㲻ϣÍû½çÃæÖÐÓÐÊý¾Ý£¬ÄÇô¾Í²»Òª°ÑËü·ÅÔÚ¶¨Òå½çÃæµÄÀàÖУ¬·Åµ½¼Ì³ÐÀàÖкÃÁË¡£²Î¿´¡°ÎªºÎÎÒ±àÒëÒ»¸ö³ÌÐòÒª»¨ÄÇô¶àʱ¼ä¡±ÌõÄ¿¡£[Òë×¢£º±¾FAQÖз²Ô­ÎÄΪdeclare/declarationµÄ¾ùÒëΪÉùÃ÷£»define/definition¾ùÒëΪ¶¨Òå¡£Á½Õߺ­ÒåÖ®»ù±¾²î±ð²Î¼ûºóÃæ¡°¡®int* p;¡¯ºÍ¡®int *p;¡¯µ½µ×ÄĸöÕýÈ·¡±ÌõÄ¿ÖеÄÒë×¢¡£Í¨³£¶øÑÔ£¬ÎÒÃÇ»¹Êǽ«ÏÂÃæµÄʾÀý´úÂë³ÆÎªcomplexÀàµÄ¶¨Ò壬¶ø½«µ¥µ¥Ò»ÐС°class complex;¡±³Æ×÷ÉùÃ÷¡£]

µ«Ò²ÓеÄʱºòÄãȷʵÐèÒª°ÑÊý¾Ý·Åµ½ÀàÉùÃ÷ÀïÃæ£¬±ÈÈçÏÂÃæµÄ¸´ÊýÀàµÄÀý×Ó£º

	template<class Scalar> class complex {
	public:
		complex() : re(0), im(0) { }
		complex(Scalar r) : re(r), im(0) { }
		complex(Scalar r, Scalar i) : re(r), im(i) { }
		// ...

		complex& operator+=(const complex& a)
			{ re+=a.re; im+=a.im; return *this; }
		// ...
	private:
		Scalar re, im;
	};

Õâ¸öcomplex£¨¸´Êý£©ÀàÊDZ»Éè¼Æ³ÉÏñC++ÄÚÖÃÀàÐÍÄÇÑùʹÓõģ¬ËùÒÔÊý¾Ý±íʾ±ØÐë³öÏÖÔÚÉùÃ÷Ö®ÖУ¬ÒÔ±ã¿ÉÒÔ½¨Á¢ÕæÕýµÄ±¾µØ¶ÔÏ󣨼´ÔÚ¶ÑÕ»ÉÏ·ÖÅäµÄ¶ÔÏ󣬶ø·ÇÔÚ¶ÑÖзÖÅ䣩£¬ÕâͬʱҲȷ±£Á˼òµ¥²Ù×÷Äܱ»ÕýÈ·ÄÚÁª»¯¡£¡°±¾µØ¶ÔÏ󡱺͡°ÄÚÁª¡±ÕâÁ½µãºÜÖØÒª£¬ÒòΪÕâÑù²Å¿ÉÒÔʹÎÒÃǵĸ´ÊýÀà´ïµ½ºÍÄÚÖø´ÊýÀàÐ͵ÄÓïÑÔÏ൱µÄЧÂÊ¡£

[Òë×¢£ºÎÒ¾õµÃBjarneµÄÕâ¶Î»Ø´ðÓе㡰ÌÓ±ÜÎÊÌ⡱֮ÏÓ¡£ÎÒÏ룬ÌáÎÊÕßµÄÕæÊµÒâͼ»òÐíÊÇÏëÖªµÀÈçºÎÓÃC++½«¡°½çÃæ¡±Ó롰ʵ×÷¡±ÍêÈ«·ÖÀë¡£²»ÐÒµÄÊÇ£¬C++ÓïÑÔºÍÀà»úÖÆ±¾Éí²»ÌṩÕâÖÖ·½Ê½¡£ÎÒÃǶ¼ÖªµÀ£¬ÀàµÄ¡°½çÃæ¡±²¿·ÖÍùÍù±»¶¨ÒåΪ¹«ÓУ¨Ò»°ãÊÇһЩÐ麯Êý£©£»¡°Êµ×÷¡±²¿·ÖÔòÍùÍù¶¨ÒåΪ±£»¤»ò˽ÓУ¨°üÀ¨º¯ÊýºÍÊý¾Ý£©£»µ«ÎÞÂÛÊÇ¡°public¡±¶Î»¹ÊÇ¡°protected¡±¡¢¡°private¡±¶Î¶¼±ØÐë³öÏÖÔÚÀàµÄÉùÃ÷ÖУ¬ËæÀàÉùÃ÷ËùÔÚµÄÍ·ÎļþÒ»ÆðÌṩ¡£ÏëÀ´Õâ¾ÍÊÇ¡°ÎªºÎÊý¾Ý±ØÐë·Åµ½ÀàÉùÃ÷ÖС±ÎÊÌâµÄÓÉÀ´°É¡£ÎªÁ˽â¾öÕâ¸öÎÊÌ⣬ÎÒÃÇÓиö±äͨµÄ°ì·¨£ºÊ¹ÓÃProxyģʽ£¨²Î¼û¡¶Design Patterns : Elements of Reusable Object-Oriented Software¡·Ò»Ê飩£¬ÎÒÃÇ¿ÉÒÔ½«Êµ×÷²¿·ÖÔÚproxyÀàÖÐÉùÃ÷£¨³ÆÎª¡°¶ÔÏó×éºÏ¡±£©£¬¶ø²»½«proxyÀàµÄÉùÃ÷±©Â¶¸øÓû§¡£ÀýÈ磺

	class Implementer; // forward declaration
	class Interface {
	public:
		// interface
	private:
		Implementer impl;
	};

ÔÚÕâ¸öÀý×ÓÖУ¬ImplementerÀà¾ÍÊÇproxy¡£ÔÚInterfaceÖб©Â¶¸øÓû§µÄÖ»ÊÇÒ»¸öimpl¶ÔÏóµÄ¡°´æ¸ù¡±£¬¶øÎÞʵ×÷ÄÚÈÝ¡£ImplementerÀà¿ÉÒÔÈçÏÂÉùÃ÷£º

	class Implementer {
public:
// implementation details, including data members

  };


ÉÏÊö´úÂëÖеÄ×¢ÊÍ´¦¿ÉÒÔ´æ·ÅÌáÎÊÕßËù˵µÄ¡°Êý¾Ý¡±£¬¶øImplementerµÄÉùÃ÷´úÂë²»Ð豩¶¸øÓû§¡£²»¹ý£¬ProxyģʽҲ²»ÊÇʮȫʮÃÀµÄ¡ª¡ªInterfaceͨ¹ýimplÖ¸Õë¼ä½Óµ÷ÓÃʵ×÷´úÂë´øÀ´Á˶îÍâµÄ¿ªÏú¡£»òÐí¶ÁÕß»á˵£¬C++²»ÊÇÓÐÄÚÁª»úÖÆÂð£¿Õâ¸ö¿ªÏúÄÜͨ¹ýÄÚÁª¶¨Òå¶øÃÖ²¹°É¡£µ«±ðÍüÁË£¬´Ë´¦ÔËÓÃProxyģʽµÄÄ¿µÄ¾ÍÊǰѡ°Êµ×÷¡±²¿·ÖÒþ²ØÆðÀ´£¬Õâ¡°Òþ²Ø¡±ÍùÍù¾ÍÒâζ×Å¡°Êµ×÷´úÂ롱ÒÔÁ´½Ó¿âÖеĶþ½øÖÆ´úÂëÐÎʽ´æÔÚ¡£Ä¿Ç°µÄC++±àÒëÆ÷ºÍÁ´½ÓÆ÷ÄÜ×öµ½¼È¡°´úÂëÄÚÁª¡±ÓÖ¡°¶þ½øÖÆÒþ²Ø¡±Â𣿻òÐí¿ÉÒÔ¡£ÄÇôProxyģʽÓÖÄÜ·ñºÍC++µÄÄ£°å»úÖÆ¡°ºÏ×÷Óä¿ì¡±ÄØ£¿£¨»»¾ä»°Ëµ£¬Èç¹ûÇ°Ãæ´úÂëÖÐInterfaceºÍImplementerµÄÉùÃ÷¾ù²»ÊÇclass£¬¶øÊÇtemplate£¬ÓÖÈçºÎÄØ£¿£©¹Ø¼üÔÚÓÚ£¬±àÒëÆ÷¶ÔÄÚÁªºÍÄ£°åµÄÖ§³Ö֮ʵ×÷ÊÇ·ñÐèÒª½øÐÐÔ´Â뿽±´£¬»¹ÊÇ¿ÉÒÔ½øÐжþ½øÖÆÂ뿽±´¡£Ä¿Ç°¶øÑÔ£¬C#µÄ·ºÐÍÖ§³Ö֮ʵ×÷ÊÇÔÚIntermediate Language²ãÃæÉϵ쬶øC++ÔòÊÇÔ´Âë²ãÃæÉϵġ£Bjarne¸ø³öµÄ¸´ÊýÀàÉùÃ÷´úÂë³Æ¡°Êý¾Ý±ØÐë³öÏÖÔÚÀàÉùÃ÷ÖС±Ò²ÊDz¿·Ö³öÓÚÕâÖÖ¿¼ÂÇ¡£ºÇºÇ£¬³¶Ô¶ÁË¡­¡­±Ï¾¹£¬Õâ¶ÎÎÄ×ÖÖ»ÊÇFAQµÄ¡°Òë×¢¡±¶øÒÑ£¬´Ë´¦²»×÷¸ü¶à̽ÌÖ£¬ÓÐÐËȤµÄ¶ÁÕß¿ÉÒÔ×Ô¼ºÈ¥Ñ°ÕÒ´ð°¸ :O) ]

Q: ΪºÎ³ÉÔ±º¯Êý²»ÊÇĬÈÏΪÐ飿

A: ÒòΪÐí¶àÀ಻ÊDZ»ÓÃÀ´×ö»ùÀàµÄ¡£[Òë×¢£ºÓÃÀ´×ö»ùÀàµÄÀà³£ÀàËÆÓÚÆäËüÓïÑÔÖеÄinterface¸ÅÄ¡ªËüÃǵÄ×÷ÓÃÊÇΪһ×éÀඨÒåÒ»¸ö¹«¹²½éÃæ¡£µ«C++ÖеÄÀàÏÔÈ»»¹ÓÐÐí¶àÆäËûÓÃ;¡ª¡ª±ÈÈç±íʾһ¸ö¾ßÌåµÄÀ©Õ¹ÀàÐÍ¡£] ÀýÈ磬¸´ÊýÀà¾ÍÊÇÈç´Ë¡£

ÁíÍ⣬ÓÐÐ麯ÊýµÄÀàÓÐÐé»úÖÆµÄ¿ªÏú[Òë×¢£ºÖ¸´æ·Åvtable´øÀ´µÄ¿Õ¼ä¿ªÏúºÍͨ¹ývtableÖеÄÖ¸Õë¼ä½Óµ÷ÓôøÀ´µÄʱ¼ä¿ªÏú]£¬Í¨³£¶øÑÔÿ¸ö¶ÔÏóÔö¼ÓµÄ¿Õ¼ä¿ªÏúÊÇÒ»¸ö×Ö³¤¡£Õâ¸ö¿ªÏú¿É²»Ð¡£¬¶øÇÒ»áÔì³ÉºÍÆäËûÓïÑÔ£¨±ÈÈçC£¬Fortran£©µÄ²»¼æÈÝÐÔ¡ª¡ªÓÐÐ麯ÊýµÄÀàµÄÄÚ´æÊý¾Ý²¼¾ÖºÍÆÕͨµÄÀàÊǺܲ»Ò»ÑùµÄ¡£[Òë×¢£ºÕâÖÖÄÚ´æÊý¾Ý²¼¾ÖµÄ¼æÈÝÐÔÎÊÌâ»á¸ø¶àÓïÑÔ»ìºÏ±à³Ì´øÀ´Âé·³¡£]

¡¶The Design and Evolution of C++¡· ÖÐÓиü¶à¹ØÓÚÉè¼ÆÀíÄîµÄϸ½Ú¡£

Q: ΪºÎÎö¹¹º¯Êý²»ÊÇĬÈÏΪÐ飿

A: ¹þ£¬Äã´ó¸ÅÖªµÀÎÒҪ˵ʲôÁË :O) ÈÔÈ»ÊÇÒòΪ¡ª¡ªÐí¶àÀ಻ÊDZ»ÓÃÀ´×ö»ùÀàµÄ¡£Ö»ÓÐÔÚÀà±»×÷ΪinterfaceʹÓÃʱÐ麯Êý²ÅÓÐÒâÒå¡££¨ÕâÑùµÄÀà³£³£ÔÚÄÚ´æ¶ÑÉÏʵÀý»¯¶ÔÏó²¢Í¨¹ýÖ¸Õë»òÒýÓ÷ÃÎÊ¡££©

ÄÇô£¬ºÎʱÎÒ¸ÃÈÃÎö¹¹º¯ÊýΪÐéÄØ£¿Å¶£¬´ð°¸ÊÇ¡ª¡ªµ±ÀàÓÐÆäËüÐ麯ÊýµÄʱºò£¬Äã¾ÍÓ¦¸ÃÈÃÎö¹¹º¯ÊýΪÐé¡£ÓÐÆäËüÐ麯Êý£¬¾ÍÒâζ×ÅÕâ¸öÀàÒª±»¼Ì³Ð£¬¾ÍÒâζ×ÅËüÓе㡰interface¡±µÄζµÀÁË¡£ÕâÑùÒ»À´£¬³ÌÐòÔ±¾Í¿ÉÄÜ»áÒÔ»ùÀàÖ¸ÕëÀ´Ö¸ÏòÓÉËüµÄ¼Ì³ÐÀàËùʵÀý»¯¶øÀ´µÄ¶ÔÏ󣬶øÄÜ·ñͨ¹ý»ùÀàÖ¸ÕëÀ´Õý³£ÊÍ·ÅÕâÑùµÄ¶ÔÏó¾ÍÒª¿´Îö¹¹º¯ÊýÊÇ·ñΪÐéÁË¡£ ÀýÈ磺

	class Base {
		// ...
		virtual ~Base();
	};

	class Derived : public Base {
		// ...
		~Derived();
	};

	void f()
	{
		Base* p = new Derived;
		delete p;	// virtual destructor used to ensure that ~Derived is called
	}

Èç¹ûBaseµÄÎö¹¹º¯Êý²»ÊÇÐéµÄ£¬ÄÇôDerivedµÄÎö¹¹º¯Êý¾Í²»»á±»µ÷Ó᪡ªÕâ³£³£»á´øÀ´¶ñ¹û£º±ÈÈ磬DerivedÖзÖÅäµÄ×ÊԴûÓб»ÊÍ·Å¡£

Q: C++ÖÐΪºÎûÓÐÐéÄâ¹¹Ô캯Êý£¿

A: ÐéÄâ»úÖÆµÄÉè¼ÆÄ¿µÄÊÇʹ³ÌÐòÔ±ÔÚ²»ÍêÈ«Á˽âϸ½Ú£¨±ÈÈçÖ»Öª¸ÃÀàʵÏÖÁËij¸ö½çÃæ£¬¶ø²»Öª¸ÃÀàÈ·ÇÐÊÇʲô¶«¶«£©µÄÇé¿öÏÂÒ²ÄÜʹÓöÔÏó¡£µ«ÊÇ£¬Òª½¨Á¢Ò»¸ö¶ÔÏ󣬿ɲ»ÄÜÖ»ÖªµÀ¡°Õâ´óÌåÉÏÊÇʲô¡±¾ÍÍêÊ¡ª¡ªÄã±ØÐëÍêÈ«Á˽âÈ«²¿Ï¸½Ú£¬Çå³þµØÖªµÀÄãÒª½¨Á¢µÄ¶ÔÏóÊǾ¿¾¹Ê²Ã´¡£ËùÒÔ£¬¹¹Ô캯Êýµ±È»²»ÄÜÊÇÐéµÄÁË¡£

²»¹ýÓÐʱÔÚ½¨Á¢¶ÔÏóʱҲÐèÒªÒ»¶¨µÄ¼ä½ÓÐÔ£¬Õâ¾ÍÐèÒªÓõ㼼ÇÉÀ´ÊµÏÖÁË¡££¨Ïê¼û¡¶The C++ Programming Language¡·£¬µÚÈý°æ£¬15.6.2£©ÕâÑùµÄ¼¼ÇÉÓÐʱҲ±»³Æ×÷¡°ÐéÄâ¹¹Ô캯Êý¡±¡£ÎÒÕâÀï¾Ù¸öʹÓóéÏóÀàÀ´¡°ÐéÄâ¹¹Ôì¶ÔÏó¡±µÄÀý×Ó£º

	struct F {	// interface to object creation functions
		virtual A* make_an_A() const = 0;
		virtual B* make_a_B() const = 0;
	};

	void user(const F& fac)
	{
		A* p = fac.make_an_A();	// make an A of the appropriate type
		B* q = fac.make_a_B();	// make a B of the appropriate type
		// ...
	}

	struct FX : F {
		A* make_an_A() const { return new AX();	} // AX is derived from A
		B* make_a_B() const { return new BX();	} // BX is derived from B
	
	};

	struct FY : F {
		A* make_an_A() const { return new AY();	} // AY is derived from A
		B* make_a_B() const { return new BY();	} // BY is derived from B

	};

	int main()
	{
		user(FX());	// this user makes AXs and BXs
		user(FY());	// this user makes AYs and BYs
		// ...
	}

¿´Ã÷°×ÁËûÓУ¿ÉÏÊö´úÂëÆäʵÔËÓÃÁËFactoryģʽµÄÒ»¸ö±äÌå¡£¹Ø¼üÖ®´¦ÊÇ£¬user()±»ÍêÈ«¹ÂÁ¢¿ªÁË¡ª¡ªËü¶ÔAX£¬AYÕâЩÀàÒ»ÎÞËùÖª¡££¨ºÙºÙ£¬ÓÐʱÎÞÖªÓÐÎÞÖªµÄºÃ´¦ ^_^£©

Q: ΪºÎÎÞ·¨ÔÚÅÉÉúÀàÖÐÖØÔØ£¿

A: Õâ¸öÎÊÌâ³£³£ÊÇÓÉÕâÑùµÄÀý×ÓÖвúÉúµÄ£º

	#include<iostream>
	using namespace std;

	class B {
	public:
		int f(int i) { cout << "f(int): "; return i+1; }
		// ...
	};

	class D : public B {
	public:
		double f(double d) { cout << "f(double): "; return d+1.3; }
		// ...
	};

	int main()
	{
		D* pd = new D;

		cout << pd->f(2) << '\n';
		cout << pd->f(2.3) << '\n';
	}

³ÌÐòÔËÐнá¹ûÊÇ£º

	f(double): 3.3
f(double): 3.6

¶ø²»ÊÇijЩÈË£¨´íÎ󵨣©²ÂÏëµÄÄÇÑù£º

	f(int): 3
f(double): 3.6

»»¾ä»°Ëµ£¬ÔÚDºÍBÖ®¼äûÓÐÖØÔØ·¢Éú¡£Äãµ÷ÓÃÁËpd->f()£¬±àÒëÆ÷¾ÍÔÚDµÄÃû×ÖÓòÀïÕÒ°¡ÕÒ£¬ÕÒµ½double f(double)ºó¾Íµ÷ÓÃËüÁË¡£±àÒëÆ÷ÀÁµÃÔÙµ½BµÄÃû×ÖÓòÀïÈ¥¿´¿´ÓÐûÓÐÄĸöº¯Êý¸ü·ûºÏÒªÇó¡£¼Çס£¬ÔÚC++ÖУ¬Ã»ÓпçÓòÖØÔØ¡ª¡ª¼Ì³ÐÀàºÍ»ùÀàËäÈ»¹ØÏµºÜÇ×ÃÜ£¬µ«Ò²²»ÄÜ»µÁËÕâÌõ¹æ¾Ø¡£Ïê¼û¡¶The Design and Evolution of C++¡·»òÕß¡¶The C++ Programming Language¡·µÚÈý°æ¡£

²»¹ý£¬Èç¹ûÄã·ÇµÃÒª¿çÓòÖØÔØ£¬Ò²²»ÊÇûÓбäͨµÄ·½·¨¡ª¡ªÄã¾Í°ÑÄÇЩº¯ÊýŪµ½Í¬Ò»¸öÓòÀïÀ´ºÃÁË¡£Ê¹ÓÃÒ»¸öusingÉùÃ÷¾Í¿ÉÒԸ㶨¡£

	class D : public B {
	public:
		using B::f;	// make every f from B available
		double f(double d) { cout << "f(double): "; return d+1.3; }
		// ...
	};

ÕâÑùÒ»À´£¬½á¹û¾ÍÊÇ

	f(int): 3
	f(double): 3.6

ÖØÔØ·¢ÉúÁË¡ª¡ªÒòΪDÖеÄÄǾä using B::f Ã÷È·¸æËß±àÒëÆ÷£¬Òª°ÑBÓòÖеÄfÒýÈ뵱ǰÓò£¬Çë±àÒëÆ÷¡°Ò»ÊÓͬÈÊ¡±¡£

Q: ÎÒÄÜ´Ó¹¹Ô캯Êýµ÷ÓÃÐ麯ÊýÂð£¿

A: ¿ÉÒÔ¡£²»¹ýÄãµÃÓÆ×ŵ㡣µ±ÄãÕâÑù×öʱ£¬Ò²ÐíÄã×Ô¼º¶¼²»ÖªµÀ×Ô¼ºÔÚ¸Éʲô£¡ÔÚ¹¹Ô캯ÊýÖУ¬ÐéÄâ»úÖÆÉÐδ·¢Éú×÷Óã¬ÒòΪ´ËʱoverridingÉÐδ·¢Éú¡£ÍòÕɸߥƽµØÆð£¬×ܵÃÏÈ´òµØ»ù°É£¿¶ÔÏóµÄ½¨Á¢Ò²ÊÇÕâÑù¡ª¡ªÏȰѻùÀ๹ÔìÍê±Ï£¬È»ºóÔÚ´Ë»ù´¡ÉϹ¹ÔìÅÉÉúÀà¡£

¿´¿´Õâ¸öÀý×Ó£º

	#include<string>
	#include<iostream>
	using namespace std;

	class B {
	public:
		B(const string& ss) { cout << "B constructor\n"; f(ss); }
		virtual void f(const string&) { cout << "B::f\n";}
	};

	class D : public B {
	public:
		D(const string & ss) :B(ss) { cout << "D constructor\n";}
		void f(const string& ss) { cout << "D::f\n"; s = ss; }
	private:
		string s;
	};

	int main()
	{
		D d("Hello");
	}

Õâ¶Î³ÌÐò¾­±àÒëÔËÐУ¬µÃµ½ÕâÑùµÄ½á¹û£º

	B constructor
B::f
D constructor
×¢Ò⣬Êä³ö²»ÊÇD::f ¡£ ¾¿¾¹·¢ÉúÁËʲô£¿f()ÊÇÔÚB::B()Öе÷Óõġ£Èç¹û¹¹Ô캯ÊýÖе÷ÓÃÐ麯ÊýµÄ¹æÔò²»ÊÇÈçǰÎÄËùÊöÄÇÑù£¬¶øÊÇÈçһЩÈËÏ£ÍûµÄÄÇÑùÈ¥µ÷ÓÃD::f()¡£ÄÇôÒòΪ¹¹Ô캯ÊýD::D()ÉÐδÔËÐУ¬×Ö·û´®s»¹Î´³õʼ»¯£¬ËùÒÔµ±D::f()ÊÔͼ½«²ÎÊý¸³¸øsʱ£¬½á¹û¶à°ëÊÇ¡ª¡ªÁ¢Âíµ±»ú¡£

Îö¹¹ÔòÕýÏà·´£¬×ñÑ­´Ó¼Ì³ÐÀൽ»ùÀàµÄ˳Ðò£¨²ð·¿×Ó×ܵôÓÉÏÍùϲð°É£¿£©£¬ËùÒÔÆäµ÷ÓÃÐ麯ÊýµÄÐÐΪºÍÔÚ¹¹Ô캯ÊýÖÐÒ»Ñù£ºÐ麯Êý´Ëʱ´Ë¿Ì±»°ó¶¨µ½ÄÄÀµ±È»Ó¦¸ÃÊÇ»ùÀàÀ²¡ª¡ªÒòΪ¼Ì³ÐÀàÒѾ­±»¡°²ð¡±ÁË¡ª¡ªÎö¹¹ÁË£¡£©£¬µ÷ÓõľÍÊÇÄĸöº¯Êý¡£

¸ü¶àϸ½ÚÇë¼û¡¶The Design and Evolution of C++¡·£¬13.2.4.2 »òÕß¡¶The C++ Programming Language¡·µÚÈý°æ£¬15.4.3 ¡£

ÓÐʱ£¬ÕâÌõ¹æÔò±»½âÊÍΪÊÇÓÉÓÚ±àÒëÆ÷µÄʵ×÷Ôì³ÉµÄ¡£[Òë×¢£º´Óʵ×÷½Ç¶È¿ÉÒÔÕâÑù½âÊÍ£ºÔÚÐí¶à±àÒëÆ÷ÖУ¬Ö±µ½¹¹Ô캯Êýµ÷ÓÃÍê±Ï£¬vtable²Å±»½¨Á¢£¬´ËʱÐ麯Êý²Å±»¶¯Ì¬°ó¶¨ÖÁ¼Ì³ÐÀàµÄͬÃûº¯Êý¡£] µ«ÊÂʵÉϲ»ÊÇÕâôһ»ØÊ¡ª¡ªÈñàÒëÆ÷ʵ×÷³É¡°¹¹Ô캯ÊýÖе÷ÓÃÐ麯ÊýÒ²ºÍ´ÓÆäËûº¯ÊýÖе÷ÓÃÒ»Ñù¡±ÊǺܼòµ¥µÄ[Òë×¢£ºÖ»Òª°ÑvtableµÄ½¨Á¢ÒÆÖÁ¹¹Ô캯Êýµ÷ÓÃ֮ǰ¼´¿É]¡£¹Ø¼ü»¹ÔÚÓÚÓïÑÔÉè¼ÆÊ±µÄ¿¼Á¿¡ª¡ªÈÃÐ麯Êý¿ÉÒÔÇóÖúÓÚ»ùÀàÌṩµÄͨÓôúÂë¡£[Òë×¢£ºÏÈÓ즻¹ÊÇÏÈÓе°£¿Bjarneʵ¼ÊÉÏÊÇÔÚ¸æËßÄ㣬²»ÊÇ¡°ÏÈÓÐʵ×÷ÔÙÓйæÔò¡±£¬¶øÊÇ¡°Èç´Ëʵ×÷£¬ÒòΪ¹æÔòÈç´Ë¡±¡£]

Q: ÓÐ"placement delete"Âð?

A: ûÓС£²»¹ýÈç¹ûÄãÕæµÄÏëÒª£¬Äã¾Í˵Â¡ªÅ¶²»£¬ÎÒµÄÒâ˼ÊÇ¡ª¡ªÄã¿ÉÒÔ×Ô¼ºÐ´Ò»¸ö¡£

ÎÒÃÇÀ´¿´¿´½«¶ÔÏó·ÅÖÁij¸öÖ¸¶¨³¡ËùµÄplacement new£º

 	class Arena {
  public:
    void* allocate(size_t);
   void deallocate(void*);
  		// ...
};

void* operator new(size_t sz, Arena& a)
{
return a.allocate(sz);
}

Arena a1(some arguments);
Arena a2(some arguments);

ÏÖÔÚÎÒÃÇ¿ÉÒÔд£º

	X* p1 = new(a1) X;
	Y* p2 = new(a1) Y;
	Z* p3 = new(a2) Z;
	// ...

µ«Ö®ºóÎÒÃÇÈçºÎÕýȷɾ³ýÕâЩ¶ÔÏó£¿Ã»ÓÐÄÚÖá°placement delete¡±µÄÀíÓÉÊÇ£¬Ã»°ì·¨Ìṩһ¸öͨÓõÄplacement delete¡£C++µÄÀàÐÍϵͳû°ì·¨ÈÃÎÒÃÇÍÆ¶Ï³öp1ÊÇÖ¸Ïò±»·ÅÖÃÔÚa1ÖеĶÔÏó¡£¼´Ê¹ÎÒÃÇÄܹ»·Ç³£Ìì²ÅµØÍÆÖªÕâµã£¬Ò»¸ö¼òµ¥µÄÖ¸Õ븳ֵ²Ù×÷Ò²»áÈÃÎÒÃÇÖØÏÝãȻ¡£²»¹ý£¬³ÌÐòÔ±±¾ÈËÓ¦¸ÃÖªµÀÔÚËû×Ô¼ºµÄ³ÌÐòÖÐʲôָÏòʲô£¬ËùÒÔ¿ÉÒÔÓнâ¾ö·½°¸£º

	template<class T> void destroy(T* p, Arena& a)
	{
		if (p) {
			p->~T();		// explicit destructor call
			a.deallocate(p);
		}
	}

ÕâÑùÎÒÃǾͿÉÒÔд£º

  destroy(p1,a1);
  destroy(p2,a2);
  destroy(p3,a3);

Èç¹ûArena×ÔÉí¸ú×Ù·ÅÖÃÆäÖеĶÔÏó£¬ÄÇôÄã¿ÉÒÔ°²È«µØÐ´³ödestroy()º¯Êý £¬°Ñ¡°±£Ö¤ÎÞ´í¡±µÄ¼à¿ØÈÎÎñ½»¸øArena£¬¶ø²»ÊÇ×Ô¼º³Ðµ£¡£

ÈçºÎÔÚÀà¼Ì³ÐÌåϵÖж¨ÒåÅä¶ÔµÄoperator new() ºÍ operator delete() ¿ÉÒԲο´ ¡¶The C++ Programming Language¡·£¬Special Edition£¬15.6½Ú £¬¡¶The Design and Evolution of C++¡·£¬10.4½Ú£¬ÒÔ¼°¡¶The C++ Programming Language¡·£¬Special Edition£¬19.4.5½Ú¡£[Òë×¢£º´Ë´¦°´Ô­ÎÄÕÕÒë¡£Ç°ÃæÓÐÌáµ½¡°²Î¼û¡¶The C++ Programming Language¡·µÚÈý°æ¡±µÄ£¬Êµ¼ÊÉÏÌØ±ð°æ£¨Special Edition£©ºÍ½Ï½üÖØÓ¡µÄµÚÈý°æÃ»Ê²Ã´Çø±ð¡£]

A: ¿ÉÒԵ쬵«ºÎ±ØÄØ£¿ºÃ°É£¬Ò²ÐíÓÐÁ½¸öÀíÓÉ£º

¸ù¾ÝÎҵľ­Ñ飬¡°Ð§ÂÊ¿¼ÂÇ¡±³£³£´¿Êô¶àÓà¡£ÔÚC++ÖУ¬Ð麯Êýµ÷ÓÃÈç´ËÖ®¿ì£¬ºÍÆÕͨº¯Êýµ÷Óò¢Ã»ÓÐÌ«¶àµÄÇø±ð¡£Çë×¢Ò⣬ֻÓÐͨ¹ýÖ¸Õë»òÕßÒýÓõ÷ÓÃʱ²Å»áÆôÓÃÐéÄâ»úÖÆ£»Èç¹ûÄãÖ¸ÃûµÀÐյص÷ÓÃÒ»¸ö¶ÔÏó£¬C++±àÒëÆ÷»á×Ô¶¯ÓÅ»¯£¬È¥³ýÈκεĶîÍ⿪Ïú¡£

Èç¹ûΪÁ˺͡°Ð麯Êýµ÷Óá±Ëµbyebye£¬ÄÇôȷʵÓиøÀà¼Ì³ÐÌåϵ¡°·â¶¥¡±µÄÐèÒª¡£ÔÚÉè¼ÆÇ°£¬²»·ÃÏÈÎÊÎÊ×Ô¼º£¬ÕâЩº¯ÊýΪºÎÒª±»Éè¼Æ³ÉÐéµÄ¡£ÎÒȷʵ¼û¹ýÕâÑùµÄÀý×Ó£ºÐÔÄÜÒªÇó¿Á¿ÌµÄº¯Êý±»Éè¼Æ³ÉÐéµÄ£¬½ö½öÒòΪ¡°ÎÒÃÇϰ¹ßÕâÑù×ö¡±£¡

ºÃÁË£¬ÎÞÂÛÈçºÎ£¬ËµÁËÄÇô¶à£¬±Ï¾¹ÄãÖ»ÊÇÏëÖªµÀ£¬ÎªÁËijÖÖºÏÀíµÄÀíÓÉ£¬ÄãÄܲ»ÄÜ·ÀÖ¹±ðÈ˼̳ÐÄãµÄÀà¡£´ð°¸ÊÇ¿ÉÒԵġ£¿Éϧ£¬ÕâÀï¸ø³öµÄ½â¾öÖ®µÀ²»¹»¸É¾»ÀûÂä¡£Äã²»µÃ²»ÔÚÔÚÄãµÄ¡°·â¶¥ÀࡱÖÐÐéÄâ¼Ì³ÐÒ»¸öÎÞ·¨¹¹ÔìµÄ¸¨Öú»ùÀà¡£»¹ÊÇÈÃÀý×ÓÀ´¸æËßÎÒÃÇÒ»Çаɣº

	class Usable;
	class Usable_lock {
friend class Usable;
private:
Usable_lock() {}
Usable_lock(const Usable_lock&) {}
};

        class Usable : public virtual Usable_lock {


// ...
public:
Usable();
Usable(char*);
// ...
};

        Usable a;

        class DD : public Usable { };

        DD dd;  // error: DD::DD() cannot access


// Usable_lock::Usable_lock(): private member

(²Î¼û¡¶The Design and Evolution of C++¡·£¬11.4.3½Ú)

Q: ΪʲôÎÒÎÞ·¨ÏÞÖÆÄ£°åµÄ²ÎÊý£¿

A: ßÀ£¬ÆäʵÄãÊÇ¿ÉÒԵġ£¶øÇÒÕâÖÖ×ö·¨²¢²»ÄÑ£¬Ò²²»ÐèҪʲô³¬³ö³£¹æµÄ¼¼ÇÉ¡£

ÈÃÎÒÃÇÀ´¿´Õâ¶Î´úÂ룺

	template<class Container>
	void draw_all(Container& c)
	{
		for_each(c.begin(),c.end(),mem_fun(&Shape::draw));
	}

Èç¹ûc²»·ûºÏconstraints£¬³öÏÖÁËÀàÐÍ´íÎó£¬ÄÇô´íÎ󽫷¢ÉúÔÚÏ൱¸´ÔÓµÄfor_each½âÎöÖ®ÖС£±ÈÈç˵£¬²ÎÊý»¯µÄÀàÐͱ»ÒªÇóʵÀý»¯intÐÍ£¬ÄÇôÎÒÃÇÎÞ·¨ÎªÖ®µ÷ÓÃShape::draw()¡£¶øÎÒÃÇ´Ó±àÒëÆ÷Öеõ½µÄ´íÎóÐÅÏ¢ÊǺ¬ºý¶øÁîÈËÃÔ»óµÄ¡ª¡ªÒòΪËüºÍ±ê×¼¿âÖи´ÔÓµÄfor_each¾À²ø²»Çå¡£

ΪÁËÔçµã²¶×½µ½Õâ¸ö´íÎó£¬ÎÒÃÇ¿ÉÒÔÕâÑùд´úÂ룺

	template<class Container>
	void draw_all(Container& c)
	{
		Shape* p = c.front(); // accept only containers of Shape*s

		for_each(c.begin(),c.end(),mem_fun(&Shape::draw));
	}

ÎÒÃÇ×¢Òâµ½£¬Ç°Ãæ¼ÓÁËÒ»ÐÐShape *pµÄ¶¨Ò壨¾¡¹Ü¾Í³ÌÐò±¾Éí¶øÑÔ£¬pÊÇÎÞÓõģ©¡£Èç¹û²»¿É½«c.front()¸³¸øShape *p£¬ÄÇô¾Í´ó¶àÊýÏÖ´ú±àÒëÆ÷¶øÑÔ£¬ÎÒÃǶ¼¿ÉÒԵõ½Ò»Ìõº¬ÒåÇåÎúµÄ³ö´íÐÅÏ¢¡£ÕâÑùµÄ¼¼ÇÉÔÚËùÓÐÓïÑÔÖж¼ºÜ³£¼û£¬¶øÇÒ¶ÔÓÚËùÓС°²»Í¬Ñ°³£µÄ¹¹Ô족¶¼²»µÃ²»Èç´Ë¡£[Òë×¢£ºÒâÖ¸¶ÔÓÚÈκÎÓïÑÔ£¬µ±ÎÒÃÇ¿ªÊ¼Ì½¼°¼«ÏÞ£¬ÄÇô²»µÃ²»Ð´Ò»Ð©¸ß¶È¼¼ÇÉÐԵĴúÂë¡£]

²»¹ýÕâÑù×ö²»ÊÇ×îºÃ¡£Èç¹ûÒªÎÒÀ´Ð´Êµ¼Ê´úÂ룬ÎÒÒ²Ðí»áÕâÑùд£º

	template<class Container>
	void draw_all(Container& c)
	{
		typedef typename Container::value_type T;
		Can_copy<T,Shape*>(); // accept containers of only Shape*s

		for_each(c.begin(),c.end(),mem_fun(&Shape::draw));
	}

Õâ¾Íʹ´úÂëͨÓÃÇÒÃ÷ÏÔµØÌåÏÖ³öÎÒµÄÒâͼ¡ª¡ªÎÒÔÚʹÓöÏÑÔ[Òë×¢£º¼´Ã÷È·¶ÏÑÔtypename ContainerÊÇdraw_all()Ëù½ÓÊܵÄÈÝÆ÷ÀàÐÍ£¬¶ø²»ÊÇÁîÈËÃÔ»óµØ¶¨ÒåÁËÒ»¸öShape *Ö¸Õ룬Ҳ²»ÖªµÀ»á²»»áÔÚºóÃæÄÄÀïÓõ½]¡£Can_copy()Ä£°å¿É±»ÕâÑù¶¨Ò壺

	template<class T1, class T2> struct Can_copy {
		static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
		Can_copy() { void(*p)(T1,T2) = constraints; }
	};

Can_copyÔÚ±àÒëÆÚ¼ä¼ì²éÈ·ÈÏT1¿É±»¸³ÓÚT2¡£Can_copy<T,Shape*>¼ì²éÈ·ÈÏTÊÇÒ»¸öShape*ÀàÐÍ£¬»òÕßÊÇÒ»¸öÖ¸ÏòShapeµÄ¹«Óм̳ÐÀàµÄÖ¸Õ룬»òÕßÊÇÓû§×Ô¶¨ÒåµÄ¿É±»×ªÐÍΪShape *µÄÀàÐÍ¡£×¢Ò⣬ÕâÀïCan_copy()µÄʵÏÖÒѾ­»ù±¾ÉÏÊÇ×îÓÅ»¯µÄÁË£ºÒ»ÐдúÂëÓÃÀ´Ö¸Ã÷ÐèÒª¼ì²éµÄconstraints[Òë×¢£ºÖ¸µÚ1ÐдúÂ룻constraintsΪT2]£¬ºÍÒª¶ÔÆä×öÕâ¸ö¼ì²éµÄÀàÐÍ[Òë×¢£ºÒª×÷¼ì²éµÄÀàÐÍΪT1] £»Ò»ÐдúÂëÓÃÀ´¾«È·ÁгöËùÒª¼ì²éÊÇ·ñÂú×ãµÄconstraints£¨constraints()º¯Êý£© [Òë×¢£ºµÚ2ÐÐÖ®ËùÒÔÒªÓÐ2¸ö×Ӿ䲢²»ÊÇÖØ¸´£¬¶øÊÇÓÐÔ­ÒòµÄ¡£Èç¹ûT1£¬T2¾ùÊÇÓû§×Ô¶¨ÒåµÄÀ࣬ÄÇôT2 c = a; ¼ì²âÄÜ·ñȱʡ¹¹Ô죻b = a; ¼ì²âÄÜ·ñ¿½±´¹¹Ôì] £»Ò»ÐдúÂëÓÃÀ´ÌṩִÐÐÕâЩ¼ì²éµÄ»ú»á [Òë×¢£ºÖ¸µÚ3ÐС£Can_copyÊÇÒ»¸öÄ£°åÀࣻconstraintsÊÇÆä³ÉÔ±º¯Êý£¬µÚ2ÐÐÖ»ÊǶ¨Ò壬¶øÎ´Ö´ÐÐ] ¡£

[Òë×¢£ºÕâÀïconstraintsʵÏֵĹؼüÊÇÒÀÀµC++Ç¿´óµÄÀàÐÍϵͳ£¬ÌرðÊÇÀàµÄ¶à̬»úÖÆ¡£µÚ2ÐдúÂëÖÐT2 c = a; b = a; Äܹ»Õý³£Í¨¹ý±àÒëµÄÌõ¼þÊÇ£ºT1ʵÏÖÁËT2µÄ½Ó¿Ú¡£¾ßÌå¶øÑÔ£¬¿ÉÄÜÊÇÒÔÏÂ4ÖÖÇé¿ö£º(1) T1£¬T2 ͬÀàÐÍ (2) ÖØÔØoperator = (3) ÌṩÁË cast operator £¨ÀàÐÍת»»ÔËËã·û£©(4) ÅÉÉúÀà¶ÔÏ󸳸ø»ùÀàÖ¸Õ롣˵µ½ÕâÀ¼ÇÆðÎÒÔøÔÚÒÔǰµÄһƪÎÄÕÂÖÐ˵µ½£¬C++µÄgenericityʵ×÷¡ª¡ªtemplate²»Ö§³Öconstrained genericity£¬¶øEiffelÔò´ÓÓï·¨¼¶±ðÖ§³Öconstrained genericity£¨¼´ÌṩÀàËÆÓÚtemplate <typename T as Comparable> xxx ÕâÑùµÄÓï·¨¡ª¡ªÆäÖÐComparable¼´ÎªÒ»¸öconstraint£©¡£ÔøÓжÁÕßÖ¸³öÎÒÕâÑù˵ÊÇ´íÎóµÄ£¬ÈÏΪC++ templateÒ²Ö§³Öconstrained genericity¡£ÏÖÔÚÕⲿ·ÖÒëÎĸø³öÁËͨ¹ýʹÓÃһЩ¼¼ÇÉ£¬½«OOPºÍGPµÄ·½·¨½áºÏ£¬´Ó¶øÔÚC++ÖÐÇÉÃîʵÏÖconstrained genericityµÄ·½·¨¡£¶ÔÓÚ°®ºÃC++µÄ¶ÁÕߣ¬ÕâÖÖ¼¼ÇÉÊÇÖµµÃϸϸƷζµÄ¡£²»¹ýÒ²²»ÒªÒòÎªÌ«Ö´ÖøÓÚ¸÷ÖÖϸ֦ĩ½ÚµÄ´úÂë¼¼ÇɶøÉ¥Ê§ÁËÈ«¾ÖÑ۹⡣ÓÐʱÓïÑÔÖ§³Ö·½ÃæµÄǷȱ¿ÉÒÔÔÚÉè¼Æ²ãÃæ£¨¶ø·Ç´úÂë²ãÃæ£©¸üÓÅÑŵØÃÖ²¹¡£ÁíÍ⣬ÕâÄܲ»ÄÜËã¡°C++µÄtemplateÖ§³Öconstrained genericity¡±£¬ÎÒ±£ÁôÒâ¼û¡£ÕýÈ磬ÓÃCͨ¹ýһЩ¼¼ÇÉÒ²¿ÉÒÔOOP£¬µ«ÎÒÃDz»ËµCÓïÑÔÖ§³ÖOOP¡£]

Çë´ó¼ÒÔÙ×¢Ò⣬ÏÖÔÚÎÒÃǵ͍Òå¾ß±¸ÁËÕâЩÎÒÃÇÐèÒªµÄÌØÐÔ£º

¼ÈÈ»Èç´Ë£¬ÎÒÃǸÉÂ𲻸ɴàÔÚC++ÓïÑÔ±¾ÉíÖж¨ÒåÀàËÆCan_copy()»òÕ߸üÓÅÑżò½àµÄÓï·¨ÄØ£¿The Design and Evolution of C++·ÖÎöÁË´Ë×ö·¨´øÀ´µÄÀ§ÄÑ¡£ÒѾ­ÓÐÐíÐí¶à¶àÉè¼ÆÀíÄ³öË®Ãæ£¬Ö»ÎªÁËÈú¬constraintsµÄÄ£°åÀàÒ×ÓÚ׫д£¬Í¬Ê±»¹ÒªÈñàÒëÆ÷ÔÚconstraints²»±»Âú×ãʱ¸ø³öÈÝÒ×Àí½âµÄ³ö´íÏûÏ¢¡£±È·½Ëµ£¬ÎÒÔÚCan_copyÖС°Ê¹Óú¯ÊýÖ¸Õ롱µÄÉè¼Æ¾ÍÀ´×ÔÓÚAlex StepanovºÍJeremy Siek¡£ÎÒÈÏΪÎÒµÄCan_copy()ʵ×÷»¹²»µ½¿ÉÒÔ±ê×¼»¯µÄ³Ì¶È¡ª¡ªËüÐèÒª¸ü¶àʵ¼ùµÄ¼ìÑé¡£ÁíÍ⣬C++ʹÓÃÕß»áÔâÓöÐí¶à²»Í¬ÀàÐ͵Äconstraints£¬Ä¿Ç°¿´À´»¹Ã»ÓÐÄÄÖÖÐÎʽµÄ´øconstraintsµÄÄ£°å»ñµÃѹµ¹¶àÊýµÄÖ§³Ö¡£

ÒÑÓв»ÉÙ¹ØÓÚconstraintsµÄ¡°ÄÚÖÃÓïÑÔÖ§³Ö¡±·½°¸±»ÌáÒéºÍʵ×÷¡£µ«ÆäʵҪ±íÊöconstraint¸ù±¾²»ÐèҪʲôÒìºõѰ³£µÄ¶«Î÷£º±Ï¾¹£¬µ±ÎÒÃÇдһ¸öÄ£°åʱ£¬ÎÒÃÇÓµÓÐC++´ø¸øÎÒÃǵÄÇ¿ÓÐÁ¦µÄ±í´ïÄÜÁ¦¡£ÈôúÂëÀ´ÎªÎҵϰ×÷Ö¤°É£º

	template<class T, class B> struct Derived_from {
		static void constraints(T* p) { B* pb = p; }
		Derived_from() { void(*p)(T*) = constraints; }
	};

	template<class T1, class T2> struct Can_copy {
		static void constraints(T1 a, T2 b) { T2 c = a; b = a; }
		Can_copy() { void(*p)(T1,T2) = constraints; }
	};

	template<class T1, class T2 = T1> struct Can_compare {
		static void constraints(T1 a, T2 b) { a==b; a!=b; a<b; }
		Can_compare() { void(*p)(T1,T2) = constraints; }
	};

	template<class T1, class T2, class T3 = T1> struct Can_multiply {
		static void constraints(T1 a, T2 b, T3 c) { c = a*b; }
		Can_multiply() { void(*p)(T1,T2,T3) = constraints; }
	};

	struct B { };
	struct D : B { };
	struct DD : D { };
	struct X { };

	int main()
	{
		Derived_from<D,B>();
		Derived_from<DD,B>();
		Derived_from<X,B>();
		Derived_from<int,B>();
		Derived_from<X,int>();

		Can_compare<int,float>();
		Can_compare<X,B>();
		Can_multiply<int,float>();
		Can_multiply<int,float,double>();
		Can_multiply<B,X>();
	
		Can_copy<D*,B*>();
		Can_copy<D,B*>();
		Can_copy<int,B*>();
	}

	// the classical "elements must derived from Mybase*" constraint:

	template<class T> class Container : Derived_from<T,Mybase> {
		// ...
	};
ÊÂʵÉÏDerived_from²¢²»¼ì²é¼Ì³ÐÐÔ£¬¶øÊǼì²é¿Éת»»ÐÔ¡£²»¹ýDerive_from³£³£ÊÇÒ»¸ö¸üºÃµÄÃû×Ö¡ª¡ªÓÐʱ¸øconstraintsÆð¸öºÃÃû×ÖÒ²ÊǼþÐèϸϸ¿¼Á¿µÄ»î¶ù¡£ Q: ÎÒÃÇÒѾ­ÓÐÁË "ÃÀºÃµÄÀÏqsort()"£¬ÎªÊ²Ã´»¹ÒªÓÃsort()?

A: ¶ÔÓÚ³õѧÕß¶øÑÔ£¬

	qsort(array,asize,sizeof(elem),elem_compare);

¿´ÉÏÈ¥Óеã¹Å¹Ö¡£»¹ÊÇ

	sort(vec.begin(),vec.end());

±È½ÏºÃÀí½â£¬Êǰɡ£ÄÇô£¬ÕâµãÀíÓɾÍ×ã¹»ÈÃÄãÉáqsort¶ø×·ÇósortÁË¡£¶ÔÓÚÀÏÊÖÀ´Ëµ£¬sort()Òª±Èqsort()¿ìµÄÊÂʵҲ»áÈÃÄãÐ͝²»ÒÑ¡£¶øÇÒsortÊÇ·ºÐ͵ģ¬¿ÉÒÔÓÃÓÚÈκκÏÀíµÄÈÝÆ÷×éºÏ¡¢ÔªËØÀàÐͺͱȽÏËã·¨¡£ÀýÈ磺

	struct Record {
		string name;
		// ...
	};

	struct name_compare {	// compare Records using "name" as the key
		bool operator()(const Record& a, const Record& b) const
			{ return a.name<b.name; }
	};

	void f(vector<Record>& vs)
	{
		sort(vs.begin(), vs.end(), name_compare());
		// ...
	}	

ÁíÍ⣬»¹ÓÐÐí¶àÈËÐÀÉÍsort()µÄÀàÐͰ²È«ÐÔ¡ª¡ªÒªÊ¹ÓÃËü¿É²»ÐèÒªÈκÎÇ¿ÖÆµÄÀàÐÍת»»¡£¶ÔÓÚ±ê×¼ÀàÐÍ£¬Ò²²»±ØÐ´compare()º¯Êý£¬Ê¡Ê²»ÉÙ¡£Èç¹ûÏë¿´¸üÏ꾡µÄ½âÊÍ£¬²Î¿´Îҵġ¶Learning Standard C++ as a New Language¡·Ò»ÎÄ¡£

ÁíÍ⣬ΪºÎsort()Òª±Èqsort()¿ì£¿ÒòΪËü¸üºÃµØÀûÓÃÁËC++µÄÄÚÁªÓï·¨ÓïÒå¡£

Q: ʲôÊÇfunction object?

A: Function objectÊÇÒ»¸ö¶ÔÏ󣬲»¹ýËüµÄÐÐΪ±íÏÖÏñº¯Êý¡£Ò»°ã¶øÑÔ£¬ËüÊÇÓÉÒ»¸öÖØÔØÁËoperator()µÄÀàËùʵÀý»¯µÃÀ´µÄ¶ÔÏó¡£

Function objectµÄº­Òå±Èͨ³£ÒâÒåÉϵĺ¯Êý¸ü¹ã·º£¬ÒòΪËü¿ÉÒÔÔÚ¶à´Îµ÷ÓÃÖ®¼ä±£³ÖijÖÖ¡°×´Ì¬¡±¡ª¡ªÕâºÍ¾²Ì¬¾Ö²¿±äÁ¿ÓÐÒìÇúͬ¹¤Ö®Ã²»¹ýÕâÖÖ¡°×´Ì¬¡±»¹¿ÉÒÔ±»³õʼ»¯£¬»¹¿ÉÒÔ´ÓÍâÃæÀ´¼ì²â£¬Õâ¿ÉÒª±È¾²Ì¬¾Ö²¿±äÁ¿Ç¿ÁË¡£ÎÒÃÇÀ´¿´Ò»¸öÀý×Ó£º

	class Sum {
		int val;
	public:
		Sum(int i) :val(i) { }
		operator int() const { return val; }		// extract value

		int operator()(int i) { return val+=i; }	// application
	};

	void f(vector v)
	{
		Sum s = 0;	// initial value 0
		s = for_each(v.begin(), v.end(), s);	// gather the sum of all elements
		cout << "the sum is " << s << "\n";
	
		// or even:
		cout << "the sum is " << for_each(v.begin(), v.end(), Sum(0)) << "\n";
	}

ÕâÀïÎÒÒªÌáÇë´ó¼Ò×¢Ò⣺һ¸öfunction object¿É±»Æ¯ÁÁµØÄÚÁª»¯(inlining)£¬ÒòΪ¶ÔÓÚ±àÒëÆ÷¶øÑÔ£¬Ã»ÓÐÌÖÑáµÄÖ¸ÕëÀ´»ìÏýÊÓÌý£¬ËùÒÔÕâÑùµÄÓÅ»¯ºÜÈÝÒ×½øÐС£[Òë×¢£ºÕâÖ¸µÄÊǽ«operator()¶¨ÒåΪÄÚÁªº¯Êý£¬¿ÉÒÔ´øÀ´Ð§ÂʵÄÌá¸ß¡£] ×÷Ϊ¶Ô±È£¬±àÒëÆ÷¼¸ºõ²»¿ÉÄÜͨ¹ýÓÅ»¯½«¡°Í¨¹ýº¯ÊýÖ¸Õëµ÷Óú¯Êý¡±ÕâÒ»²½ÖèËù»¨µÄ¿ªÏúÊ¡µô£¬ÖÁÉÙĿǰÈç´Ë¡£

ÔÚ±ê×¼¿âÖÐfunction objects±»¹ã·ºÊ¹Óã¬Õâ¸ø±ê×¼¿â´øÀ´Á˼«´óµÄÁé»îÐԺͿÉÀ©Õ¹ÐÔ¡£

[Òë×¢£ºC++ÊÇÒ»¸ö²©²ÉÖÚ³¤µÄÓïÑÔ£¬function objectµÄ¸ÅÄî¾ÍÊÇ´Ófunctional programmingÖнèÀ´µÄ£»¶øC++±¾ÉíµÄÇ¿´óºÍ±íÏÖÁ¦µÄ·á¸»Ò²Ê¹ÕâÖÖ¡°ÄÃÀ´Ö÷Ò塱³ÉΪ¿ÉÄÜ¡£Ò»°ã¶øÑÔ£¬ÔÚʹÓÃfunction objectµÄµØ·½Ò²³£¿ÉÒÔʹÓú¯ÊýÖ¸Õ룻ÔÚÎÒÃÇ»¹²»ÊìϤfunction objectµÄʱºòÎÒÃÇÒ²³£³£ÊÇʹÓÃÖ¸ÕëµÄ¡£µ«¶¨ÒåÒ»¸öº¯ÊýÖ¸ÕëµÄÓï·¨¿É²»ÊÇÌ«¼òµ¥Ã÷ÁË£¬¶øÇÒÔÚC++ÖÐÖ¸ÕëÔçÒѱ³ÉÏÁË¡°´íÎóÖ®Ô´¡±µÄ¶ñÃû¡£¸üºÎ¿ö£¬Í¨¹ýÖ¸Õëµ÷Óú¯ÊýÔö¼ÓÁ˼ä½Ó¿ªÏú¡£ËùÒÔ£¬ÎÞÂÛΪÁËÓï·¨µÄÓÅÃÀ»¹ÊÇЧÂʵÄÌá¸ß£¬¶¼Ó¦¸ÃÌᳫʹÓÃfunction objects¡£

ÏÂÃæÎÒÃÇÔÙ´ÓÉè¼ÆÄ£Ê½µÄ½Ç¶ÈÀ´¸üÉîÈëµØÀí½âfunction objects£ºÕâÊÇVisitorģʽµÄµäÐÍÓ¦Óᣵ±ÎÒÃÇÒª¶Ôij¸ö/ijЩ¶ÔÏóÊ©¼ÓijÖÖ²Ù×÷£¬µ«ÓÖ²»Ï뽫ÕâÖÖ²Ù×÷ÏÞ¶¨ËÀ£¬ÄÇô¾Í¿ÉÒÔ²ÉÓÃVisitorģʽ¡£ÔÚDesign PatternsÒ»ÊéÖУ¬×÷Õß°ÑÕâÖÖģʽʵ×÷Ϊ£ºÍ¨¹ýÒ»¸öVisitorÀàÀ´ÌṩÕâÖÖ²Ù×÷£¨ÔÚÇ°ÃæBjarne StroustrupµÄ´úÂëÖУ¬Sum¾ÍÊÇÒ»¸öVisitorµÄ±äÌ壩£¬ÓÃVisitorÀàʵÀý»¯Ò»¸övisitor¶ÔÏ󣨵±È»£¬ÔÚÇ°ÃæµÄ´úÂëÖжÔÓ¦µÄÊÇs£©£»È»ºóÔÚIteratorµÄµü´ú¹ý³ÌÖУ¬ÎªÃ¿Ò»¸ö¶ÔÏóµ÷ÓÃvisitor.visit()¡£ÕâÀïvisit()ÊÇVisitorÀàµÄÒ»¸ö³ÉÔ±º¯Êý£¬×÷ÓÃÏ൱ÓÚSumÀàÖÐÄǸö¡°ÌØÊâµÄ³ÉÔ±º¯Êý¡±¡ª¡ªoperator()£»visit()Ò²ÍêÈ«¿ÉÒÔ±»¶¨ÒåΪÄÚÁªº¯Êý£¬ÒÔÈ¥³ý¼ä½ÓÐÔ£¬Ìá¸ßÐÔÄÜ¡£ÔÚ´ËÌáÇë¶ÁÕß×¢Ò⣬C++°ÑÖØÔØµÄ²Ù×÷·ûÒ²¿´×÷º¯Êý£¬Ö»²»¹ýÊǾßÓÐÌØÊ⺯ÊýÃûµÄº¯Êý¡£ËùÒÔʵ¼ÊÉÏDesign PatternsÒ»ÊéÖÐVisitorģʽµÄʾ·¶Êµ×÷ºÍÕâÀïfunction objectµÄʵ×÷´óÌåÉÏÊǵȼ۵ġ£Ò»¸öfunction objectÒ²¾ÍÊÇÒ»¸öÌØÊâµÄVisitor¡£]

Q: ÎÒÓ¦¸ÃÔõÑù´¦ÀíÄÚ´æÐ¹Â©£¿

A: ºÜ¼òµ¥£¬Ö»ÒªÐ´¡°²»Â©¡±µÄ´úÂë¾ÍÍêÊÂÁ˰¡¡£ÏÔÈ»£¬Èç¹ûÄãµÄ´úÂëµ½´¦ÊÇnew¡¢delete¡¢Ö¸ÕëÔËË㣬ÄÇÄãÏëÈÃËü¡°²»Â©¡±¶¼ÄÑ¡£²»¹ÜÄãÓжàôСÐĽ÷É÷£¬¾ýΪÈË£¬·ÇÉñÒ²£¬´íÎóÔÚËùÄÑÃâ¡£×îÖÕÄã»á±»×Ô¼ºÔ½À´Ô½¸´ÔӵĴúÂë±Æ·èµÄ¡ª¡ªÄ㽫ͶÉíÓÚÓëÄÚ´æÐ¹Â©µÄ·Ü¶·Ö®ÖУ¬¶ÔbugÃDz»Àë²»Æú£¬Ö±ÖÁɽ·åûÓÐÀâ½Ç£¬µØÇò²»ÔÙת¶¯¡£¶øÄÜÈÃÄã±ÜÃâÕâÑùÀ§¾³µÄ¼¼ÇÉÒ²²»¸´ÔÓ£ºÄãÖ»ÒªÒÐÖØÒþº¬ÔÚÄ»ºóµÄ·ÖÅä»úÖÆ¡ª¡ª¹¹ÔìºÍÎö¹¹£¬ÈÃC++µÄÇ¿´óµÄÀàϵͳÀ´ÖúÄãÒ»±ÛÖ®Á¦¾ÍOKÁË¡£±ê×¼¿âÖеÄÄÇЩÈÝÆ÷¾ÍÊǺܺõÄʵÀý¡£ËüÃÇÈÃÄã²»±Ø»¯·Ñ´óÁ¿µÄʱ¼ä¾«Á¦Ò²ÄÜÇáËÉã«ÒâµØ¹ÜÀíÄÚ´æ¡£ÎÒÃÇÀ´¿´¿´ÏÂÃæµÄʾÀý´úÂ롪¡ªÉèÏëһϣ¬Èç¹ûûÓÐÁËstringºÍvector£¬ÊÀ½ç½«»áÔõÑù£¿Èç¹û²»ÓÃËüÃÇ£¬ÄãÄܵÚÒ»´Î¾Íд³öºÁÎÞÄÚ´æ´íÎóµÄͬÑù¹¦ÄÜ´úÂëÂð£¿

	#include<vector>
	#include<string>
	#include<iostream>
	#include<algorithm>
	using namespace std;

	int main()	// small program messing around with strings
	{
		cout << "enter some whitespace-separated words:\n";
		vector<string> v;
		string s;
		while (cin>>s) v.push_back(s);

		sort(v.begin(),v.end());

		string cat;
		typedef vector<string>::const_iterator Iter;
		for (Iter p = v.begin(); p!=v.end(); ++p) cat += *p+"+";
		cout << cat << '\n';
	}

Çë×¢ÒâÕâÀïûÓÐÏÔʽµÄÄÚ´æ¹ÜÀí´úÂ롣ûÓк꣬ûÓÐÀàÐÍת»»£¬Ã»ÓÐÒç³ö¼ì²â£¬Ã»ÓÐÇ¿ÖÆµÄ´óСÏÞÖÆ£¬Ò²Ã»ÓÐÖ¸Õë¡£Èç¹ûʹÓÃfunction objectºÍ±ê×¼Ëã·¨[Òë×¢£ºÖ¸±ê×¼¿âÖÐÌṩµÄ·ºÐÍËã·¨]£¬ÎÒÁ¬IteratorÒ²¿ÉÒÔ²»Óᣲ»¹ýÕâ±Ï¾¹Ö»ÊÇÒ»¸öС³ÌÐò£¬É±¼¦ÑÉÓÃÅ£µ¶£¿

µ±È»£¬ÕâЩ·½·¨Ò²²¢·ÇÎÞи¿É»÷£¬¶øÇÒ˵ÆðÀ´ÈÝÒ××öÆðÀ´ÄÑ£¬ÒªÏµÍ³µØÊ¹ÓÃËüÃÇÒ²²¢²»×ÜÊǺܼòµ¥¡£²»¹ý£¬ÎÞÂÛÈçºÎ£¬ËüÃǵĹ㷺ÊÊÓÃÐÔÁîÈ˾ªÑÈ£¬¶øÇÒͨ¹ýÒÆÈ¥´óÁ¿µÄÏÔʽÄÚ´æ·ÖÅä/ÊÍ·Å´úÂ룬ËüÃÇȷʵÔöÇ¿ÁË´úÂëµÄ¿É¶ÁÐԺͿɹÜÀíÐÔ¡£ÔçÔÚ1981Ä꣬ÎÒ¾ÍÖ¸³öͨ¹ý´ó·ù¶È¼õÉÙÐèÒªÏÔʽ¼ÓÒÔ¹ÜÀíµÄ¶ÔÏóÊýÁ¿£¬Ê¹ÓÃC++¡°½«ÊÂÇé×ö¶Ô¡±½«²»ÔÙÊÇÒ»¼þ¼«Æä·ÑÉñµÄ¼è¾ÞÈÎÎñ¡£

Èç¹ûÄãµÄÓ¦ÓÃÁìÓòûÓÐÄÜÔÚÄÚ´æ¹ÜÀí·½ÃæÖúÄãÒ»±ÛÖ®Á¦µÄÀà¿â£¬ÄÇôÈç¹ûÄ㻹ÏëÈÃÄãµÄÈí¼þ¿ª·¢±äµÃ¼È¿ì½ÝÓÖÄÜÇáËɵõ½ÕýÈ·½á¹û£¬×îºÃÊÇÏȽ¨Á¢ÕâÑùÒ»¸ö¿â¡£

Èç¹ûÄãÎÞ·¨ÈÃÄÚ´æ·ÖÅäºÍÊͷųÉΪ¶ÔÏóµÄ¡°×ÔÈ»ÐÐΪ¡±£¬ÄÇôÖÁÉÙÄã¿ÉÒÔͨ¹ýʹÓÃ×ÊÔ´¾ä±úÀ´¾¡Á¿±ÜÃâÄÚ´æÐ¹Â©¡£ÕâÀïÊÇÒ»¸öʾÀý£º¼ÙÉèÄãÐèÒª´Óº¯Êý·µ»ØÒ»¸ö¶ÔÏó£¬Õâ¸ö¶ÔÏóÊÇÔÚ×ÔÓÉÄÚ´æ¶ÑÉÏ·ÖÅäµÄ£»Äã¿ÉÄÜ»áÍü¼ÇÊÍ·ÅÄǸö¶ÔÏ󡪡ª±Ï¾¹ÎÒÃÇÎÞ·¨Í¨¹ý¼ì²éÖ¸ÕëÀ´È·¶¨ÆäÖ¸ÏòµÄ¶ÔÏóÊÇ·ñÐèÒª±»ÊÍ·Å£¬ÎÒÃÇÒ²ÎÞ·¨µÃ֪˭Ӧ¸Ã¸ºÔðÊÍ·ÅËü¡£ÄÇô£¬¾ÍÓÃ×ÊÔ´¾ä±ú°É¡£±ÈÈ磬±ê×¼¿âÖеÄauto_ptr¾Í¿ÉÒÔ°ïÖú³ÎÇ壺¡°ÊͷŶÔÏó¡±ÔðÈξ¿¾¹ÔÚË­¡£ÎÒÃÇÀ´¿´£º

	#include<memory>
	#include<iostream>
	using namespace std;

	struct S {
		S() { cout << "make an S\n"; }
		~S() { cout << "destroy an S\n"; }
		S(const S&) { cout << "copy initialize an S\n"; }
		S& operator=(const S&) { cout << "copy assign an S\n"; }
	};

	S* f()
	{
		return new S;	// who is responsible for deleting this S?
	};

	auto_ptr<S> g()
	{
		return auto_ptr<S>(new S);	// explicitly transfer responsibility for deleting this S
	}

	int main()
	{
		cout << "start main\n";
		S* p = f();
		cout << "after f() before g()\n";
	//	S* q = g();	// caught by compiler
		auto_ptr<S> q = g();
		cout << "exit main\n";
		// leaks *p
		// implicitly deletes *q
	}

ÕâÀïÖ»ÊÇÄÚ´æ×ÊÔ´¹ÜÀíµÄÀý×Ó£»ÖÁÓÚÆäËüÀàÐ͵Ä×ÊÔ´¹ÜÀí£¬¿ÉÒÔÈç·¨ÅÚÖÆ¡£

Èç¹ûÔÚÄãµÄ¿ª·¢»·¾³ÖÐÎÞ·¨ÏµÍ³µØÊ¹ÓÃÕâÖÖ·½·¨£¨±È·½Ëµ£¬ÄãʹÓÃÁ˵ÚÈý·½ÌṩµÄ¹Å¶­´úÂ룬»òÕßÔ¶¹Å¡°Ñ¨¾ÓÈË¡±²ÎÓëÁËÄãµÄÏîÄ¿¿ª·¢£©£¬ÄÇôÄãÔÚ¿ª·¢¹ý³ÌÖпÉǧÍòÒª¼ÇסʹÓÃÄÚ´æ·À©¼ì²â³ÌÐò£¬»òÕ߸ɴàʹÓÃÀ¬»øÊÕ¼¯Æ÷£¨Garbage Collector£©¡£

Q: ΪºÎ²¶×½µ½Òì³£ºó²»ÄܼÌÐøÖ´ÐкóÃæµÄ´úÂëÄØ?

A: Õâ¸öÎÊÌ⣬»»¾ä»°ËµÒ²¾ÍÊÇ£ºÎªÊ²Ã´C++²»ÌṩÕâÑùÒ»¸öÔ­ÓÄÜʹÄã´¦ÀíÒì³£¹ýºó·µ»Øµ½Òì³£Å׳ö´¦¼ÌÐøÍùÏÂÖ´ÐУ¿[Òë×¢£º±ÈÈ磬һ¸ö¼òµ¥µÄresumeÓï¾ä£¬Ó÷¨ºÍÒÑÓеÄreturnÓï¾äÀàËÆ£¬Ö»²»¹ý±ØÐë·ÅÔÚexception handlerµÄ×îºó¡£]

àÅ£¬´ÓÒì³£´¦Àí´úÂë·µ»Øµ½Òì³£Å׳ö´¦¼ÌÐøÖ´ÐкóÃæµÄ´úÂëµÄÏë·¨ºÜºÃ[Òë×¢£ºÏÖÐÐÒì³£»úÖÆµÄÉè¼ÆÊÇ£ºµ±Òì³£±»Å׳öºÍ´¦Àíºó£¬´Ó´¦Àí´úÂëËùÔÚµÄÄǸöcatch¿éÍùÏÂÖ´ÐÐ]£¬µ«Ö÷ÒªÎÊÌâÔÚÓÚ¡ª¡ªexception handler²»¿ÉÄÜÖªµÀΪÁËÈúóÃæµÄ´úÂëÕý³£ÔËÐУ¬ÐèÒª×ö¶àÉÙÇå³ýÒì³£µÄ¹¤×÷[Òë×¢£º±Ï¾¹£¬µ±ÓÐÒì³£·¢Éú£¬ÊÂÇé¾ÍÓе㲻̫¶Ô¾¢ÁË£¬²»ÊÇÂ𣻸üºÎ¿öÊÕʰÀÃ̯×ÓÓÀÔ¶ÊǼþÂé·³µÄÊÂ]£¬ËùÒÔ£¬Èç¹ûÒªÈá°¼ÌÐøÖ´ÐС±Äܹ»Õý³£¹¤×÷£¬Ð´throw´úÂëµÄÈ˺Íдcatch´úÂëµÄÈ˱ØÐë¶Ô±Ë´ËµÄ´úÂë¶¼ºÜÊìϤ£¬¶øÕâ¾Í´øÀ´Á˸´ÔÓµÄÏ໥ÒÀÀµ¹ØÏµ[Òë×¢£º¼ÈÖ¸¿ª·¢ÈËÔ±Ö®¼äµÄ¡°Ï໥ÒÀÀµ¡±£¬Ò²Ö¸´úÂë¼äµÄÏ໥ÒÀÀµ¡ª¡ª½ôñîºÏµÄ´úÂë¿É²»ÊǺôúÂëŶ :O) ]£¬»á´øÀ´ºÜ¶àÂé·³µÄά»¤ÎÊÌâ¡£

ÔÚÎÒÉè¼ÆC++µÄÒì³£´¦Àí»úÖÆµÄʱºò£¬ÎÒÔøÈÏÕæµØ¿¼ÂǹýÕâ¸öÎÊÌ⣻ÔÚC++±ê×¼»¯µÄ¹ý³ÌÖУ¬Õâ¸öÎÊÌâÒ²±»ÏêϸµØÌÖÂÛ¹ý¡££¨²Î¼û¡¶The Design and Evolution of C++¡·ÖйØÓÚÒì³£´¦ÀíµÄÕ½ڣ©Èç¹ûÄãÏëÊÔÊÔ¿´ÔÚÅ׳öÒ쳣֮ǰÄܲ»Äܽâ¾öÎÊÌâÈ»ºó¼ÌÐøÍùÏÂÖ´ÐУ¬Äã¿ÉÒÔÏȵ÷ÓÃÒ»¸ö¡°¼ì²é¡ª»Ö¸´¡±º¯Êý£¬È»ºó£¬Èç¹û»¹ÊDz»Äܽâ¾öÎÊÌ⣬ÔÙ°ÑÒì³£Å׳ö¡£Ò»¸öÕâÑùµÄÀý×ÓÊÇnew_handler¡£

Q: ΪºÎC++ÖÐûÓÐCÖÐrealloc()µÄ¶ÔÓ¦Î

A: Èç¹ûÄãÒ»¶¨ÏëÒªµÄ»°£¬Ä㵱Ȼ¿ÉÒÔʹÓÃrealloc()¡£²»¹ý£¬realloc() Ö»ºÍͨ¹ýmalloc()Ö®ÀàCº¯Êý·ÖÅäµÃµ½µÄÄÚ´æ¡°ºÏ×÷Óä¿ì¡±£¬ÔÚ·ÖÅäµÄÄÚ´æÖв»ÄÜÓо߱¸Óû§×Ô¶¨Òå¹¹Ô캯ÊýµÄ¶ÔÏó¡£Çë¼Çס£ºÓëijЩÌìÕæµÄÈËÃǵÄÏëÏóÏà·´£¬realloc()±ØÒªÊ±Êǻ´±´´ó¿éµÄÄڴ浽зÖÅäµÄÁ¬Ðø¿Õ¼äÖеġ£ËùÒÔ£¬reallocûʲôºÃµÄ ^_^

ÔÚC++ÖУ¬´¦ÀíÄÚ´æÖØ·ÖÅäµÄ½ÏºÃ°ì·¨ÊÇʹÓñê×¼¿âÖеÄÈÝÆ÷£¬±ÈÈçvector¡£[Òë×¢£ºÕâЩÈÝÆ÷»á×Ô¼º¹ÜÀíÐèÒªµÄÄڴ棬ÔÚ±ØÒªÊ±»á¡°Ôö³¤³ß´ç¡±¡ª¡ª½øÐÐÖØ·ÖÅä¡£]

Q: ÎÒÈçºÎʹÓÃÒì³£´¦Àí£¿

A: ²Î¼û¡¶The C++ Programming Language¡·14ÕÂ8.3½Ú£¬ÒÔ¼°¸½Â¼E¡£¸½Â¼EÖ÷Òª²ûÊöÈçºÎ׫д¡°exception-safe¡±´úÂ룬Õâ¸ö¸½Â¼¿É²»ÊÇд¸ø³õѧÕß¿´µÄ¡£Ò»¸ö¹Ø¼ü¼¼ÇÉÊÇ¡°×ÊÔ´·ÖÅä¼´³õʼ»¯¡±¡ª¡ªÕâÖÖ¼¼ÇÉͨ¹ý¡°ÀàµÄÎö¹¹º¯Êý¡±¸øÒ×Ôì³É»ìÂҵġ°×ÊÔ´¹ÜÀí¡±´øÀ´ÁË¡°ÖÈÐòµÄÊï¹â¡±¡£

Q: ÎÒÈçºÎ´Ó±ê×¼ÊäÈëÖжÁÈ¡string£¿

A: Èç¹ûÒª¶ÁÒÔ¿Õ°×½áÊøµÄµ¥¸öµ¥´Ê£¬¿ÉÒÔÕâÑù£º

	#include<iostream>
	#include<string>
	using namespace std;

	int main()
	{
		cout << "Please enter a word:\n";

		string s;
		cin>>s;
	
		cout << "You entered " << s << '\n';
	}

Çë×¢Ò⣬ÕâÀïûÓÐÏÔʽµÄÄÚ´æ¹ÜÀí´úÂ룬ҲûÓÐÏÞÖÆ³ß´ç¶ø¿ÉÄܻ᲻СÐÄÒç³öµÄ»º³åÇø¡£ [Òë×¢£ºËƺõBjarne³£½¾°ÁµØÐû³ÆÕâµã¡ª¡ªÒòΪÕâÊÇstringÄËÖÁÕû¸ö±ê×¼¿â´øÀ´µÄÖØ´óºÃ´¦Ö®Ò»£¬È·ÊµÖµµÃ×ÔºÀ£»¶øÔÚÀϵÄCÓïÑÔÖУ¬×îÈóÌÐòÔ±±§Ô¹µÄÒ²ÊÇÄÚÖÃ×Ö·û´®ÀàÐ͵Äȱ·¦ÒÔ¼°ÓÉ´ËÒýÆðµÄ¡°²Ù×÷×Ö·û´®ËùÐèÒªÖ®¸´ÔÓÄÚ´æ¹ÜÀí´ëÊ©¡±Ëù´øÀ´µÄÂé·³¡£BjarneÒ»¶¨ÔÚµÃÒâµØÏ룬¡°¹þ£¬ÎҵĽÐC++µÄСbabyÖÕÓÚ³¤´óÁË£¬Ç÷ÏòÍêÃÀÁË£¡¡± :O) ]

Èç¹ûÄãÐèÒªÒ»´Î¶ÁÒ»ÕûÐУ¬¿ÉÒÔÕâÑù£º

	#include<iostream>
	#include<string>
	using namespace std;

	int main()
	{
		cout << "Please enter a line:\n";

		string s;
		getline(cin, s);
	
		cout << "You entered " << s << '\n';
	}

¹ØÓÚ±ê×¼¿âËùÌṩ֮¹¦Äܵļò½é£¨ÖîÈçiostream£¬stream£©£¬²Î¼û¡¶The C++ Programming Language¡·µÚÈý°æµÄµÚÈýÕ¡£Èç¹ûÏë¿´CºÍC++µÄÊäÈëÊä³ö¹¦ÄÜʹÓÃÖ®¾ßÌå±È½Ï£¬²Î¿´Îҵġ¶Learning Standard C++ as a New Language¡·Ò»ÎÄ¡£

Q: ΪºÎC++²»Ìṩ¡°finally¡±½á¹¹£¿

A: ÒòΪC++ÌṩÁËÁíÒ»ÖÖ»úÖÆ£¬ÍêÈ«¿ÉÒÔÈ¡´úfinally£¬¶øÇÒÕâÖÖ»úÖÆ¼¸ºõ×ÜÒª±Èfinally¹¤×÷µÃ¸üºÃ£º¾ÍÊÇ¡ª¡ª¡°·ÖÅä×ÊÔ´¼´³õʼ»¯¡±¡££¨¼û¡¶The C++ Programming Language¡·14.4½Ú£©»ù±¾µÄÏë·¨ÊÇ£¬ÓÃÒ»¸ö¾Ö²¿¶ÔÏóÀ´·â×°Ò»¸ö×ÊÔ´£¬ÕâÑùÒ»À´¾Ö²¿¶ÔÏóµÄÎö¹¹º¯Êý¾Í¿ÉÒÔ×Ô¶¯ÊÍ·Å×ÊÔ´¡£ÕâÑù£¬³ÌÐòÔ±¾Í²»»á¡°Íü¼ÇÊÍ·Å×ÊÔ´¡±ÁË¡£ [Òë×¢£ºÒòΪC++µÄ¶ÔÏó¡°ÉúÃüÖÜÆÚ¡±»úÖÆÌæËû¼ÇסÁË :O) ] ÏÂÃæÊÇÒ»¸öÀý×Ó£º

	class File_handle {
		FILE* p;
	public:
		File_handle(const char* n, const char* a)
			{ p = fopen(n,a); if (p==0) throw Open_error(errno); }
		File_handle(FILE* pp)
			{ p = pp; if (p==0) throw Open_error(errno); }

		~File_handle() { fclose(p); }

		operator FILE*() { return p; }

		// ...
	};

	void f(const char* fn)
	{
		File_handle f(fn,"rw");	// open fn for reading and writing
		// use file through f
	}

ÔÚÒ»¸öϵͳÖУ¬Ã¿Ò»Ñù×ÊÔ´¶¼ÐèÒªÒ»¸ö¡°×ÊÔ´¾Ö±ú¡±¶ÔÏ󣬵«ÎÒÃDz»±ØÎªÃ¿Ò»¸ö×ÊÔ´¶¼Ð´Ò»¸ö¡°finally¡±Óï¾ä¡£ÔÚʵ×÷µÄϵͳÖУ¬×ÊÔ´µÄ»ñÈ¡ºÍÊͷŵĴÎÊýÔ¶Ô¶¶àÓÚ×ÊÔ´µÄÖÖÀ࣬ËùÒÔ¡°×ÊÔ´·ÖÅä¼´³õʼ»¯¡±»úÖÆ²úÉúµÄ´úÂëÒª±È¡°finally¡±»úÖÆÉÙ¡£

[Òë×¢£ºObject Pascal£¬Java£¬C#µÈÓïÑÔ¶¼ÓÐfinallyÓï¾ä¿é£¬³£ÓÃÓÚ·¢ÉúÒ쳣ʱ¶Ô±»·ÖÅä×ÊÔ´µÄ×ÊÔ´µÄ´¦Àí¡ª¡ªÕâÒâζ×ÅÓжàÉٴηÖÅä×ÊÔ´¾ÍÓжàÉÙfinallyÓï¾ä¿é£¨ÉÙÁËÒ»¸öfinally¾ÍÒâζ×ÅÓÐһЩ×ÊÔ´·ÖÅä²»ÊÇ¡°exception safe¡±µÄ£©£»¶ø¡°×ÊÔ´·ÖÅä¼´³õʼ»¯¡±»úÖÆ½«Ô­±¾·ÅÔÚfinally¿éÖеĴúÂëÒÆµ½ÁËÀàµÄÎö¹¹º¯ÊýÖС£ÎÒÃÇÖ»ÐèΪÿһÀà×ÊÔ´Ìṩһ¸ö·â×°À༴¿É¡£Ðè´úÂëÁ¿Êë¶àÊëÉÙ£¿³ý·ÇÄãµÄϵͳÖÐÿһÀà×ÊÔ´¶¼Ö»±»Ê¹ÓÃÒ»´Î¡ª¡ªÕâÖÖÇé¿öÏ´úÂëÁ¿ÊÇÏàµÈµÄ£»·ñÔòÓÀÔ¶ÊÇǰÕß¶àÓÚºóÕß :O) ]

ÁíÍ⣬Çë¿´¿´¡¶The C++ Programming Language¡·¸½Â¼EÖеÄ×ÊÔ´¹ÜÀíÀý×Ó¡£

Q: ÄǸöauto_ptrÊÇʲô¶«¶«°¡£¿ÎªÊ²Ã´Ã»ÓÐauto_array£¿

A: Ŷ£¬auto_ptrÊÇÒ»¸öºÜ¼òµ¥µÄ×ÊÔ´·â×°À࣬ÊÇÔÚ<memory>Í·ÎļþÖж¨ÒåµÄ¡£ËüʹÓá°×ÊÔ´·ÖÅä¼´³õʼ»¯¡±¼¼ÊõÀ´±£Ö¤×ÊÔ´ÔÚ·¢ÉúÒ쳣ʱҲÄܱ»°²È«ÊÍ·Å£¨¡°exception safety¡±£©¡£Ò»¸öauto_ptr·â×°ÁËÒ»¸öÖ¸Õ룬Ҳ¿ÉÒÔ±»µ±×÷Ö¸ÕëÀ´Ê¹Óᣵ±ÆäÉúÃüÖÜÆÚµ½Á˾¡Í·£¬auto_ptr»á×Ô¶¯ÊÍ·ÅÖ¸Õë¡£ÀýÈ磺

	#include<memory>
	using namespace std;

	struct X {
		int m;
		// ..
	};

	void f()
	{
		auto_ptr<X> p(new X);
		X* q = new X;

		p->m++;		// use p just like a pointer
		q->m++;
		// ...

		delete q;
	}
Èç¹ûÔÚ´úÂëÓÃ// ...±ê×¢µÄµØ·½Å׳öÒì³££¬ÄÇôp»á±»Õý³£É¾³ý¡ª¡ªÕâ¸ö¹¦ÀÍÓ¦¸Ã¼ÇÔÚauto_ptrµÄÎö¹¹º¯ÊýÍ·ÉÏ¡£²»¹ý£¬qÖ¸ÏòµÄXÀàÐͶÔÏó¾ÍûÓб»ÊÍ·Å£¨ÒòΪ²»ÊÇÓÃauto_ptr¶¨ÒåµÄ£©¡£ÏêÇéÇë¼û¡¶The C++ Programming Language¡·14.4.2½Ú¡£

Auto_ptrÊÇÒ»¸öÇáÁ¿¼¶µÄÀ࣬ûÓÐÒýÈëÒýÓüÆÊý»úÖÆ¡£Èç¹ûÄã°ÑÒ»¸öauto_ptr£¨±ÈÈ磬ap1£©¸³¸øÁíÒ»¸öauto_ptr£¨±ÈÈ磬ap2£©£¬ÄÇôap2½«³ÖÓÐʵ¼ÊÖ¸Õ룬¶øap1½«³ÖÓÐÁãÖ¸Õë¡£ÀýÈ磺

	#include<memory>
	#include<iostream>
	using namespace std;

	struct X {
		int m;
		// ..
	};

	int main()
	{
		auto_ptr<X> p(new X);
		auto_ptr<X> q(p);
		cout << "p " << p.get() << " q " << q.get() << "\n";
	}

ÔËÐнá¹ûÓ¦¸ÃÊÇÏÈÏÔʾһ¸öÁãÖ¸Õ룬Ȼºó²ÅÊÇÒ»¸öʵ¼ÊÖ¸Õ룬¾ÍÏñÕâÑù£º

	p 0x0 q 0x378d0

auto_ptr::get()·µ»ØÊµ¼ÊÖ¸Õë¡£

ÕâÀÓïÒåËÆºõÊÇ¡°×ªÒÆ¡±£¬¶ø·Ç¡°¿½±´¡±£¬Õâ»òÐíÓеãÁîÈ˾ªÑÈ¡£ÌرðҪעÒâµÄÊÇ£¬²»Òª°Ñauto_ptr×÷Ϊ±ê×¼ÈÝÆ÷µÄ²ÎÊý¡ª¡ª±ê×¼ÈÝÆ÷ÒªÇóͨ³£µÄ¿½±´ÓïÒå¡£ÀýÈ磺

	std::vector<auto_ptr<X> >v;	// error

Ò»¸öauto_ptrÖ»ÄܳÖÓÐÖ¸Ïòµ¥¸öÔªËØµÄÖ¸Õ룬¶ø²»ÊÇÊý×éÖ¸Õ룺

	void f(int n)
	{
		auto_ptr<X> p(new X[n]);	// error
		// ...
	}

ÉÏÊö´úÂë»á³ö´í£¬ÒòΪÎö¹¹º¯ÊýÊÇʹÓÃdelete¶ø·Çdelete[]À´ÊÍ·ÅÖ¸ÕëµÄ£¬ËùÒÔºóÃæµÄn-1¸öXûÓб»ÊÍ·Å¡£

ÄÇô£¬¿´À´ÎÒÃÇÓ¦¸ÃÓÃÒ»¸öʹÓÃdelete[]À´ÊÍ·ÅÖ¸ÕëµÄ£¬½Ðauto_arrayµÄÀàËÆ¶«¶«À´·ÅÊý×éÁË£¿Å¶£¬²»£¬²»£¬Ã»ÓÐʲôauto_array¡£ÀíÓÉÊÇ£¬²»ÐèÒªÓа¡¡ª¡ªÎÒÃÇÍêÈ«¿ÉÒÔÓÃvectorÂ

	void f(int n)
	{
		vector<X> v(n);
		// ...
	}

Èç¹ûÔÚ // ... ²¿·Ö·¢ÉúÁËÒì³££¬vµÄÎö¹¹º¯Êý»á±»×Ô¶¯µ÷Óá£

Q: CºÍC++·ç¸ñµÄÄÚ´æ·ÖÅä/ÊÍ·Å¿ÉÒÔ»ìÓÃÂð£¿

A: ¿ÉÒÔ¡ª¡ª´ÓÄã¿ÉÔÚÒ»¸ö³ÌÐòÖÐͬʱʹÓÃmalloc()ºÍnewµÄÒâÒåÉ϶øÑÔ¡£

²»¿ÉÒÔ¡ª¡ª´ÓÄãÎÞ·¨deleteÒ»¸öÒÔmalloc()·ÖÅä¶øÀ´Ö®¶ÔÏóµÄÒâÒåÉ϶øÑÔ¡£ÄãÒ²ÎÞ·¨free()»òrealloc()Ò»¸öÓÉnew·ÖÅä¶øÀ´µÄ¶ÔÏó¡£

C++µÄnewºÍdeleteÔËËã·ûÈ·±£¹¹ÔìºÍÎö¹¹Õý³£·¢Éú£¬µ«C·ç¸ñµÄmalloc()¡¢calloc()¡¢free()ºÍrealloc()¿É²»±£Ö¤Õâµã¡£¶øÇÒ£¬Ã»ÓÐÈκÎÈËÄÜÏòÄãµ£±££¬new/deleteºÍmalloc/freeËùÕÆ¿ØµÄÄÚ´æÊÇÏ໥¡°¼æÈÝ¡±µÄ¡£Èç¹ûÔÚÄãµÄ´úÂëÖУ¬Á½ÖÖ·ç¸ñ»ìÓöøÃ»ÓиøÄãÔì³ÉÂé·³£¬ÄÇÎÒÖ»ÄÜ˵£ºÖ±µ½Ä¿Ç°ÎªÖ¹£¬ÄãÊǷdz£ÐÒÔ赀 :O)

Èç¹ûÄãÒòΪ˼Äî¡°ÃÀºÃµÄÀÏrealloc()¡±£¨Ðí¶àÈ˶¼Ë¼ÄîËý£©¶øÎÞ·¨¸îÉáÕû¸ö¹ÅÀϵÄCÄÚ´æ·ÖÅä»úÖÆ£¨°®Îݼ°ÎÚ£¿£©£¬ÄÇô¿¼ÂÇʹÓñê×¼¿âÖеÄvector°É¡£ÀýÈ磺

	// read words from input into a vector of strings:

	vector<string> words;
	string s;
	while (cin>>s && s!=".") words.push_back(s);

Vector»á°´ÐèÒª×Ô¶¯Ôö³¤µÄ¡£

Îҵġ¶Learning Standard C++ as a New Language¡·Ò»ÎÄÖиø³öÁËÆäËüÀý×Ó£¬¿ÉÒԲο¼¡£

Q: ÎÒÏë´Óvoid *ת»»£¬ÎªÊ²Ã´±ØÐëʹÓû»ÐÍ·û£¿

A: ÔÚCÖУ¬Äã¿ÉÒÔÒþʽת»»£¬µ«ÕâÊDz»°²È«µÄ£¬ÀýÈ磺

	#include<stdio.h>

	int main()
	{
		char i = 0;
		char j = 0;
		char* p = &i;
		void* q = p;
		int* pp = q;	/* unsafe, legal C, not C++ */

		printf("%d %d\n",i,j);
		*pp = -1;	/* overwrite memory starting at &i */
		printf("%d %d\n",i,j);
	}

Èç¹ûÄãʹÓÃT*ÀàÐ͵ÄÖ¸Õ룬¸ÃÖ¸ÕëÈ´²»Ö¸ÏòTÀàÐ͵ĶÔÏ󣬺ó¹û¿ÉÄÜÊÇÔÖÄÑÐԵģ»ËùÒÔÔÚC++ÖÐÈç¹ûÄãÒª½«void*»»ÐÍΪT*£¬Äã±ØÐëʹÓÃÏÔʽ»»ÐÍ£º

	int* pp = (int*)q;

»òÕߣ¬¸üºÃµÄÊÇ£¬Ê¹ÓÃÐµĻ»ÐÍ·û£¬ÒÔʹ»»ÐͲÙ×÷¸üΪÐÑÄ¿£º

	int* pp = static_cast<int*>(q);

µ±È»£¬×îºÃµÄ»¹ÊÇ¡ª¡ª²»Òª»»ÐÍ¡£

ÔÚCÖÐÒ»Àà×î³£¼ûµÄ²»°²È«»»ÐÍ·¢ÉúÔÚ½«malloc()·ÖÅä¶øÀ´µÄÄڴ渳¸øÄ³¸öÖ¸Õë֮ʱ£¬ÀýÈ磺

	int* p = malloc(sizeof(int));

ÔÚC++ÖУ¬Ó¦¸ÃʹÓÃÀàÐͰ²È«µÄnew²Ù×÷·û£º

	int* p = new int;

¶øÇÒ£¬new»¹Óи½´øµÄºÃ´¦£º

ÀýÈ磺 

	typedef std::complex<double> cmplx;

	/* C style: */
	cmplx* p = (cmplx*)malloc(sizeof(int));	/* error: wrong size */
							/* forgot to test for p==0 */
	if (*p == 7) { /* ... */ }			/* oops: forgot to initialize *p */

	// C++ style:
	cmplx* q = new cmplx(1,2); // will throw bad_alloc if memory is exhausted
	if (*q == 7) { /* ... */ }
A: ÈçºÎÔÚÀàÖж¨Òå³£Á¿£¿

Q: Èç¹ûÄãÏëµÃµ½Ò»¸ö¿ÉÓÃÓÚ³£Á¿±í´ïʽÖеij£Á¿£¬ÀýÈçÊý×é´óСµÄ¶¨Ò壬ÄÇôÄãÓÐÁ½ÖÖÑ¡Ôñ£º

	class X {
		static const int c1 = 7;
		enum { c2 = 19 };

		char v1[c1];
		char v2[c2];

		// ...
	};
Ò»ÑÛÍûÈ¥£¬c1µÄ¶¨ÒåËÆºõ¸ü¼ÓÖ±½ØÁ˵±£¬µ«±ðÍüÁËÖ»ÓÐstaticµÄÕûÐÍ»òö¾ÙÐÍÁ¿²ÅÄÜÈç´Ë³õʼ»¯¡£Õâ¾ÍºÜÓоÖÏÞÐÔ£¬ÀýÈ磺
	class Y {
		const int c3 = 7;		// error: not static
		static int c4 = 7;		// error: not const
		static const float c5 = 7;	// error not integral
	};
ÎÒ»¹ÊǸüϲ»¶Íæ¡°enumÏ··¨¡±£¬ÒòΪÕâÖÖ¶¨Òå¿ÉÒÆÖ²ÐԺ㬶øÇÒ²»»áÒýÓÕÎÒȥʹÓ÷DZê×¼µÄ¡°ÀàÄÚ³õʼ»¯¡±À©Õ¹Óï·¨¡£

ÄÇô£¬ÎªºÎÒªÓÐÕâЩ²»·½±ãµÄÏÞÖÆ£¿ÒòΪÀàͨ³£ÉùÃ÷ÔÚÍ·ÎļþÖУ¬¶øÍ·ÎļþÍùÍù±»Ðí¶àµ¥ÔªËù°üº¬¡£[ËùÒÔ£¬Àà¿ÉÄÜ»á±»ÖØ¸´ÉùÃ÷¡£]µ«ÊÇ£¬ÎªÁ˱ÜÃâÁ´½ÓÆ÷Éè¼ÆµÄ¸´ÔÓ»¯£¬C++ÒªÇóÿ¸ö¶ÔÏó¶¼Ö»Äܱ»¶¨ÒåÒ»´Î¡£Èç¹ûC++ÔÊÐíÀàÄÚ¶¨ÒåÒª×÷Ϊ¶ÔÏó±»´æÔÚÄÚ´æÖеÄʵÌ壬ÄÇôÕâÏîÒªÇó¾ÍÎÞ·¨Âú×ãÁË¡£¹ØÓÚC++Éè¼ÆÊ±µÄһЩÕÛÖÔ£¬²Î¼û¡¶The Design and Evolution of C++¡·¡£

Èç¹ûÕâ¸ö³£Á¿²»ÐèÒª±»ÓÃÓÚ³£Á¿±í´ïʽ£¬ÄÇôÄãµÄÑ¡ÔñÓàµØ¾Í±È½Ï´óÁË£º

	class Z {
		static char* p;		// initialize in definition
		const int i;		// initialize in constructor
	public:
		Z(int ii) :i(ii) { }
	};

	char* Z::p = "hello, there";

Ö»Óе±static³ÉÔ±ÊÇÔÚÀàÍâ±»¶¨ÒåµÄ£¬Äã²Å¿ÉÒÔ»ñÈ¡ËüµÄµØÖ·£¬ÀýÈ磺

	class AE {
		// ...
	public:
		static const int c6 = 7;
		static const int c7 = 31;
	};

	const int AE::c7;	// definition

	int f()
	{
		const int* p1 = &AE::c6;	// error: c6 not an lvalue
		const int* p2 = &AE::c7;	// ok
		// ...
	}
Q: ΪºÎdelete²Ù×÷²»°ÑÖ¸ÕëÖÃÁ㣿

A: àÅ£¬ÎʵÃͦÓеÀÀíµÄ¡£ÎÒÃÇÀ´¿´£º

	delete p;
	// ...
	delete p;

Èç¹û´úÂëÖеÄ//...²¿·ÖûÓÐÔٴθøp·ÖÅäÄڴ棬ÄÇôÕâ¶Î´úÂë¾Í¶ÔͬһƬÄÚ´æÊÍ·ÅÁËÁ½´Î¡£ÕâÊǸöÑÏÖØµÄ´íÎ󣬿ÉϧC++ÎÞ·¨ÓÐЧµØ×èÖ¹ÄãдÕâÖÖ´úÂë¡£²»¹ý£¬ÎÒÃǶ¼ÖªµÀ£¬ÊÍ·Å¿ÕÖ¸ÕëÊÇÎÞΣº¦µÄ£¬ËùÒÔÈç¹ûÔÚÿһ¸ödelete p;ºóÃæ¶¼½ô½ÓÒ»¸öp = 0;£¬ÄÇôÁ½´ÎÊÍ·ÅͬһƬÄÚ´æµÄ´íÎó¾Í²»»á·¢ÉúÁË¡£¾¡¹ÜÈç´Ë£¬ÔÚC++ÖÐûÓÐÈκÎÓï·¨¿ÉÒÔÇ¿ÖÆ³ÌÐòÔ±ÔÚÊÍ·ÅÖ¸ÕëºóÁ¢¿Ì½«¸ÃÖ¸Õë¹éÁã¡£ËùÒÔ£¬¿´À´±ÜÃâ·¸ÕâÑùµÄ´íÎóµÄÖØÈÎÖ»ÄÜÈ«ÂäÔÚ³ÌÐòÔ±¼çÉÏÁË¡£»òÐí£¬delete×Ô¶¯°ÑÖ¸Õë¹éÁãÕæÊǸöºÃÖ÷Ò⣿

Ŷ£¬²»²»£¬Õâ¸öÖ÷Òâ²»¹»¡°ºÃ¡±¡£Ò»¸öÀíÓÉÊÇ£¬±»deleteµÄÖ¸Õëδ±ØÊÇ×óÖµ¡£ÎÒÃÇÀ´¿´£º

	delete p+1;
	delete f(x);

ÄãÈÃdelete°Ñʲô×Ô¶¯ÖÃÁ㣿ҲÐíÕâÑùµÄÀý×Ó²»³£¼û£¬µ«×ã¿ÉÖ¤Ã÷¡°delete×Ô¶¯°ÑÖ¸Õë¹éÁ㡱²¢²»±£ÏÕ¡£[Òë×¢£ºÊÂʵÉÏ£¬ÎÒÃÇÕæÕýÏëÒªµÄÊÇ£º¡°ÈκÎÖ¸Ïò±»ÊͷŵÄÄÚ´æÇøÓòµÄÖ¸Õë¶¼±»×Ô¶¯¹éÁ㡱¡ª¡ªµ«¿Éϧ³ýÁËGarbage CollectorÍâûʲô¶«¶«¿ÉÒÔ×öµ½Õâµã¡£] ÔÙÀ´¿´¸ö¼òµ¥Àý×Ó£º

	T* p = new T;
	T* q = p;
	delete p;
	delete q;	// ouch!

C++±ê×¼ÆäʵÔÊÐí±àÒëÆ÷ʵ×÷Ϊ¡°×Ô¶¯°Ñ´«¸ødeleteµÄ×óÖµÖÃÁ㡱£¬ÎÒҲϣÍû±àÒëÆ÷³§ÉÌÕâÑù×ö£¬µ«¿´À´³§ÉÌÃDz¢²»Ï²»¶ÕâÑù¡£Ò»¸öÀíÓɾÍÊÇÉÏÊöÀý×Ó¡ª¡ªµÚ3ÐÐÓï¾äÈç¹ûdelete°Ñp×Ô¶¯ÖÃÁãÁËÓÖÈçºÎÄØ£¿qÓÖûÓб»×Ô¶¯ÖÃÁ㣬µÚ4ÐÐÕÕÑù³ö´í¡£

Èç¹ûÄã¾õµÃÊÍ·ÅÄÚ´æÊ±°ÑÖ¸ÕëÖÃÁãºÜÖØÒª£¬ÄÇô²»·ÁдÕâÑùÒ»¸ödestroyº¯Êý£º

	template<class T> inline void destroy(T*& p) { delete p; p = 0; }

²»·Á°Ñdelete´øÀ´µÄÂé·³¿´×÷¡°¾¡Á¿ÉÙÓÃnew/delete£¬¶àÓñê×¼¿âÖеÄÈÝÆ÷¡±Ö®ÁíÒ»ÌõÀíÓÉ°É :O)

Çë×¢Ò⣬°ÑÖ¸Õë×÷ΪÒýÓô«µÝ£¨ÒÔ±ãdelete¿ÉÒÔ°ÑÖ¸ÕëÖÃÁ㣩»á´øÀ´¶îÍâµÄÐ§Òæ¡ª¡ª·ÀÖ¹ÓÒÖµ±»´«µÝ¸ødestroy() £º

	int* f();
	int* p;
	// ...
	destroy(f());	// error: trying to pass an rvalue by non-const reference
	destroy(p+1);	// error: trying to pass an rvalue by non-const reference
Q: ÎÒ¿ÉÒÔд"void main()"Âð£¿

A: ÕâÑùµÄ¶¨Òå

	void main() { /* ... */ }

²»ÊÇC++£¬Ò²²»ÊÇC¡££¨²Î¼ûISO C++ ±ê×¼ 3.6.1[2] »ò ISO C ±ê×¼ 5.1.2.2.1£© Ò»¸ö×ñ´Ó±ê×¼µÄ±àÒëÆ÷ʵ×÷Ó¦¸Ã½ÓÊÜ

	int main() { /* ... */ }

ºÍ 

	int main(int argc, char* argv[]) { /* ... */ }

±àÒëÆ÷Ò²¿ÉÒÔÌṩmain()µÄ¸ü¶àÖØÔØ°æ±¾£¬²»¹ýËüÃǶ¼±ØÐë·µ»Øint£¬Õâ¸öintÊÇ·µ»Ø¸øÄãµÄ³ÌÐòµÄµ÷ÓÃÕߵģ¬ÕâÊÇÖÖ¡°¸ºÔ𡱵Ä×ö·¨£¬¡°Ê²Ã´¶¼²»·µ»Ø¡±¿É²»´óºÃŶ¡£Èç¹ûÄã³ÌÐòµÄµ÷ÓÃÕß²»Ö§³ÖÓá°·µ»ØÖµ¡±À´½»Á÷£¬Õâ¸öÖµ»á±»×Ô¶¯ºöÂÔ¡ª¡ªµ«ÕâÒ²²»ÄÜʹvoid main()³ÉΪºÏ·¨µÄC++»òC´úÂë¡£¼´Ê¹ÄãµÄ±àÒëÆ÷Ö§³ÖÕâÖÖ¶¨Ò壬×îºÃÒ²²»ÒªÑø³ÉÕâÖÖϰ¹ß¡ª¡ª·ñÔòÄã¿ÉÄܱ»ÆäËûC/C++ÈÏΪdz±¡ÎÞ֪Ŷ¡£

ÔÚC++ÖУ¬Èç¹ûÄãÏÓÂé·³£¬¿ÉÒÔ²»±ØÏÔʽµØÐ´³öreturnÓï¾ä¡£±àÒëÆ÷»á×Ô¶¯·µ»Ø0¡£ÀýÈ磺

	#include<iostream>

	int main()
	{
		std::cout << "This program returns the integer value 0\n";
	}

Âé·³Â𣿲»Âé·³£¬int main()±Èvoid main()»¹ÉÙÁËÒ»¸ö×ÖďĨ :O)ÁíÍ⣬»¹ÒªÇëÄã×¢Ò⣺ÎÞÂÛÊÇISO C++»¹ÊÇC99¶¼²»ÔÊÐíÄãÊ¡ÂÔ·µ»ØÀàÐͶ¨Òå¡£ÕâÒ²¾ÍÊÇ˵£¬ºÍC89¼°ARM C++[Òë×¢£ºÖ¸Margaret EllisºÍBjarne StroustrupÓÚ1990ÄêºÏÖøµÄ¡¶The Annotated C++ Reference Manual¡·ÖÐÃèÊöµÄC++]²»Í¬£¬int²¢²»ÊÇȱʡ·µ»ØÖµ¡£ËùÒÔ£¬

	#include<iostream>

	main() { /* ... */ }

»á³ö´í£¬ÒòΪmain()º¯ÊýȱÉÙ·µ»ØÀàÐÍ¡£

Q: ΪºÎÎÒ²»ÄÜÖØÔØ¡°.¡±¡¢¡°::¡±ºÍ¡°sizeof¡±µÈ²Ù×÷·û£¿

A: ´ó²¿·ÖµÄ²Ù×÷·ûÊÇ¿ÉÒÔ±»ÖØÔصģ¬ÀýÍâµÄÖ»ÓС°.¡±¡¢¡°::¡±¡¢¡°?:¡±ºÍ¡°sizeof¡±¡£Ã»ÓÐʲô·Ç½ûÖ¹operator?:ÖØÔØµÄÀíÓÉ£¬Ö»²»¹ýûÓбØÒª¶øÒÑ¡£ÁíÍ⣬expr1?expr2:expr3µÄÖØÔØº¯ÊýÎÞ·¨±£Ö¤expr2ºÍexpr3ÖÐÖ»ÓÐÒ»¸ö±»Ö´ÐС£

¶ø¡°sizeof¡±ÎÞ·¨±»ÖØÔØÊÇÒòΪ²»ÉÙÄÚ²¿²Ù×÷£¬±ÈÈçÖ¸Õë¼Ó·¨£¬¶¼ÒÀÀµÓÚËü£¬ÀýÈ磺

	X a[10];
	X* p = &a[3];
	X* q = &a[3];
	p++;	// p points to a[4]
		// thus the integer value of p must be
		// sizeof(X) larger than the integer value of q

ÕâÑù£¬sizeof(X)ÎÞ·¨ÔÚ²»Î¥±³»ù±¾ÓïÑÔ¹æÔòµÄǰÌáϱí´ïʲôеÄÓïÒå¡£

ÔÚN::mÖУ¬NºÍm¶¼²»ÊDZí´ïʽ£¬ËüÃÇÖ»ÊDZàÒëÆ÷¡°ÈÏʶ¡±µÄÃû×Ö£¬¡°::¡±Ö´ÐеÄʵ¼Ê²Ù×÷ÊDZàÒëʱµÄÃû×ÖÓò½âÎö£¬²¢Ã»Óбí´ïʽµÄÔËËãÇ£ÉæÔÚÄÚ¡£»òÐíÓÐÈË»á¾õµÃÖØÔØÒ»¸ö¡°x::y¡±£¨ÆäÖÐxÊÇʵ¼Ê¶ÔÏ󣬶ø·ÇÃû×ÖÓò»òÀàÃû£©ÊÇÒ»¸öºÃÖ÷Ò⣬µ«ÕâÑù×öÒýÈëÁËеÄÓï·¨[Òë×¢£ºÖØÔصı¾ÒâÊÇÈòÙ×÷·û¿ÉÒÔÓÐеÄÓïÒ壬¶ø²»ÊǸü¸ÄÓï·¨¡ª¡ª·ñÔò»áÒýÆð»ìÂÒ]£¬Îҿɲ»ÈÏΪÐÂÓï·¨´øÀ´µÄ¸´ÔÓÐÔ»á¸øÎÒÃÇʲôºÃ´¦¡£

Ô­ÔòÉÏÀ´Ëµ£¬¡°.¡±ÔËËã·ûÊÇ¿ÉÒÔ±»ÖØÔص쬾ÍÏñ¡°->¡±Ò»Ñù¡£²»¹ý£¬Õâ»á´øÀ´ÓïÒåµÄ»ìÏý¡ª¡ªÎÒÃǵ½µ×ÊÇÏëºÍ¡°.¡±ºóÃæµÄ¶ÔÏó´ò½»µÀÄØ£¬»¹ÊÇ¡°.¡±ºóÃæµÄ¶«¶«Ëùʵ¼ÊÖ¸ÏòµÄʵÌå´ò½»µÀÄØ£¿¿´¿´Õâ¸öÀý×Ó£¨Ëü¼ÙÉè¡°.¡±ÖØÔØÊÇ¿ÉÒԵģ©£º

	class Y {
	public:
		void f();
		// ...
	};

	class X {	// assume that you can overload .
		Y* p;
		Y& operator.() { return *p; }
		void f();
		// ...
	};

	void g(X& x)
	{
		x.f();	// X::f or Y::f or error?
	}

Õâ¸öÎÊÌâÓкü¸ÖÖ½â¾ö·½°¸¡£ÔÚC++±ê×¼»¯Ö®Ê±£¬ºÎÖÖ·½°¸Îª¼Ñ²¢²»Ã÷ÏÔ¡£Ï¸½ÚÇë²Î¼û¡¶The Design and Evolution of C++¡·¡£

Q: ÎÒÔõÑù²ÅÄܰÑÕûÊýת»¯Îª×Ö·û´®£¿

A: ×î¼òµ¥µÄ·½·¨ÊÇʹÓÃstringstream £º

	#include<iostream>
	#include<string>
	#include<sstream>
	using namespace std;

	string itos(int i)	// convert int to string
	{
		stringstream s;
		s << i;
		return s.str();
	}

	int main()
	{
		int i = 127;
		string ss = itos(i);
		const char* p = ss.c_str();

		cout << ss << " " << p << "\n";
	}

µ±È»£¬ºÜ×ÔÈ»µØ£¬Äã¿ÉÒÔÓÃÕâÖÖ·½·¨À´°ÑÈκοÉͨ¹ý¡°<<¡±Êä³öµÄÀàÐÍת»¯Îªstring¡£ÏëÖªµÀstringÁ÷µÄϸ½ÚÂ𣿲μû¡¶The C++ Programming Language¡·£¬21.5.3½Ú¡£

Q: ¡°int* p;¡±ºÍ¡°int *p;¡±£¬µ½µ×ÄĸöÕýÈ·£¿

A: Èç¹ûÈüÆËã»úÀ´¶Á£¬Á½ÕßÍêÈ«µÈͬ£¬¶¼ÊÇÕýÈ·µÄ¡£ÎÒÃÇ»¹¿ÉÒÔÉùÃ÷³É¡°int * p¡±»ò¡°int*p¡±¡£±àÒëÆ÷²»»áÀí»áÄãÊDz»ÊÇÔÚÄÄÀï¶à·ÅÁ˼¸¸ö¿Õ¸ñ¡£

²»¹ýÈç¹ûÈÃÈËÀ´¶Á£¬Á½Õߵĺ¬Òå¾ÍÓÐËù²»Í¬ÁË¡£´úÂëµÄÊéд·ç¸ñÊǺÜÖØÒªµÄ¡£C·ç¸ñµÄ±í´ïʽºÍÉùÃ÷ʽ³£±»¿´×÷±È¡°necessary evil¡±[Òë×¢£º¡°±ØÒªÖ®¶ñ¡±£¬ÒâָΪÁ˴ﵽijÖÖÄ¿µÄ¶ø²»µÃ²»¸¶³öµÄ´ú¼Û¡£ÀýÈçÓÐÈËÈÏΪ»·¾³µÄÆÆ»µÊǾ­¼Ã·¢Õ¹´øÀ´µÄ¡°necessary evil¡±]¸üÔãµÄ¶«Î÷£¬¶øC++ÔòºÜÇ¿µ÷ÀàÐÍ¡£ËùÒÔ£¬¡°int *p¡±ºÍ¡°int* p¡±Ö®¼ä²¢ÎÞ¶Ô´íÖ®·Ö£¬Ö»Óзç¸ñÖ®Õù¡£

Ò»¸öµäÐ͵ÄC³ÌÐòÔ±»áд¡°int *p¡±£¬¶øÇÒÕñÕñÓдʵظæËßÄã¡°Õâ±íʾ¡®*pÊÇÒ»¸öint¡¯¡±¡ª¡ªÌýÉÏȥͦÓеÀÀíµÄ¡£ÕâÀ*ºÍp°óÔÚÁËÒ»Æð¡ª¡ªÕâ¾ÍÊÇCµÄ·ç¸ñ¡£ÕâÖÖ·ç¸ñÇ¿µ÷µÄÊÇÓï·¨¡£

¶øÒ»¸öµäÐ͵ÄC++³ÌÐòÔ±»áд¡°int* p¡±£¬²¢¸æËßÄã¡°pÊÇÒ»¸öÖ¸ÏòintµÄÖ¸Õ룬pµÄÀàÐÍÊÇint*¡±¡£ÕâÖÖ·ç¸ñÇ¿µ÷µÄÊÇÀàÐÍ¡£µ±È»£¬ÎÒϲ»¶ÕâÖÖ·ç¸ñ :O) ¶øÇÒ£¬ÎÒÈÏΪ£¬ÀàÐÍÊǷdz£ÖØÒªµÄ¸ÅÄÎÒÃÇÓ¦¸Ã×¢ÖØÀàÐÍ¡£ËüµÄÖØÒªÐÔË¿ºÁ²»ÑÇÓÚC++ÓïÑÔÖÐµÄÆäËü¡°½ÏΪ¸ß¼¶µÄ²¿·Ö¡±¡£[Òë×¢£ºÖîÈçRTTI£¬¸÷ÖÖcast£¬template»úÖÆµÈ£¬¿É³ÆÎª¡°½Ï¸ß¼¶µÄ²¿·Ö¡±Á˰ɣ¬µ«ËüÃÇÆäʵҲÊÇÀàÐ͸ÅÄîµÄÀ©Õ¹ºÍÔËÓá£ÎÒÔøÐ´¹ýÁ½ÆªÌ¸µ½C++ºÍOOPµÄÎÄÕ·¢±íÔÚ±¾¿¯ÉÏ£¬ÎÄÖж¼Ç¿µ÷ÁËÀí½â¡°ÀàÐÍ¡±Ö®ÖØÒªÐÔ¡£ÎÒ»¹ÔøÒë¹ýObject Unencapsulated £¨Õâ±¾ÊéÓÉ×÷ÕßÏÈǰËùÖøÔÚÍøÉϹãΪÁ÷´«µÄC++?? A CritiqueÐÞ¶©¶øÀ´£©Öн²ÀàÐ͵ÄÕ½ڣ¬Õâ±¾ÊéµÄ×÷ÕßÉõÖÁ³ÆObject Oriented ProgrammingÓ¦¸ÃÕýÃûΪType Oriented Programming¡ª¡ª¡°ÃæÏòÀàÐͱà³Ì¡±£¡ÕâÓеã½ÃÍ÷¹ýÕýÁË£¬µ«ÀàÐÍÈ·ÊDZà³ÌÓïÑÔÖ®ºËÐIJ¿·Ö¡£]

µ±ÉùÃ÷µ¥¸ö±äÁ¿Ê±£¬int *ºÍint*µÄ²î±ð²¢²»ÊÇÌØ±ðÍ»³ö£¬µ«µ±ÎÒÃÇÒªÒ»´ÎÉùÃ÷¶à¸ö±äÁ¿Ê±£¬Ò×»ìÏýÖ®´¦¾ÍÈ«±©Â¶³öÀ´ÁË£º

	int* p, p1;	// probable error: p1 is not an int*

ÕâÀp1µÄÀàÐ͵½µ×ÊÇint»¹ÊÇint *ÄØ£¿°Ñ*·ÅµÃÀëp½üÒ»µãҲͬÑù²»ÄܳÎÇåÎÊÌ⣺

	int *p, p1;	// probable error?

¿´À´ÎªÁ˱£ÏÕÆð¼û£¬Ö»ºÃÒ»´ÎÉùÃ÷Ò»¸ö±äÁ¿ÁË¡ª¡ªÌرðÊǵ±ÉùÃ÷°éËæ×ųõʼ»¯Ö®Ê±¡£[Òë×¢£º±¾FAQÖз²Ô­ÎÄΪdeclare/declarationµÄ¾ùÒëΪÉùÃ÷£»define/definition¾ùÒëΪ¶¨Ò塣ͨ³£ÈÏΪ£¬Á½Õߺ­ÒåÖ®»ù±¾²î±ðÊÇ£º¡°ÉùÃ÷¡±Ö»ÊÇΪ±àÒëÆ÷ÌṩÐÅÏ¢£¬ÈñàÒëÆ÷ÔÚ·ûºÅ±íÖÐΪ±»ÉùÃ÷µÄ·ûºÅ£¨±ÈÈçÀàÐÍÃû£¬±äÁ¿Ãû£¬º¯ÊýÃûµÈ£©±£ÁôλÖ㬶ø²»ÓÃÖ¸Ã÷¸Ã·ûºÅËù¶ÔÓ¦µÄ¾ßÌåÓïÒ塪¡ª¼´£ºÃ»ÓÐÈκÎÄÚ´æ¿Õ¼äµÄ·ÖÅä»òÕßʵ¼Ê¶þ½øÖÆ´úÂëµÄÉú³É¡£¶ø¡°¶¨Ò塱ÔòÐëÖ¸Ã÷ÓïÒ塪¡ªÈç¹û°Ñ¡°ÉùÃ÷¡±±È×÷ÔڴǵäÖÐΪһ¸öдʱ£ÁôÌõÄ¿£»ÄÇô¡°¶¨Ò塱¾ÍºÃ±ÈÔÚÌõÄ¿ÖжÔÕâ¸ö´ÊµÄÒâ˼¡¢Ó÷¨¸ø³öÏêϸ½âÊÍ¡£µ±ÎÒÃÇ˵һ¸öC++Óï¾äÊÇ¡°¶¨Ò塱£¬ÄÇô±àÒëÆ÷±Ø¶¨»áΪ¸ÃÓï¾ä²úÉú¶ÔÓ¦µÄ»úÆ÷Ö¸Áî»òÕß·ÖÅäÄڴ棬¶ø±»³ÆÎª¡°ÉùÃ÷¡±µÄÓï¾äÔò²»»á±»±àÒë³öÈκÎʵ¼Ê´úÂë¡£´ÓÕâ¸ö½Ç¶È¶øÑÔ£¬Ô­ÎÄÖÐÓÐЩµØ·½Ëä×÷ÕßдµÄÊÇ¡°¶ÔÏó¡¢Àà¡¢ÀàÐ͵ÄÉùÃ÷£¨declaration£©¡±£¬µ«»òÐí¸ÄÒëΪ¡°¶¨Ò塱½Ï·ûºÏÎÒÃǵÄÀí½â¡£²»¹ý±¾ÒëÎÄ»¹ÊDzÉÓÃÖÒÓÚÔ­ÎĵÄÒë·¨£¬²¢²»°´ÕÕÎÒµÄÀí½â¶ø¼ÓÒÔ¸ü¸Ä¡£ÌØ´Ë˵Ã÷¡£ÁíÍ⣬ÒëÎÄÖз²Éæ¼°ÎÒ¸öÈ˶ÔÔ­ÎĵÄÀí½â¡¢²¹³äÖ®²¿·Ö¾ùÒÔÒë×¢ÐÎʽ¸ø³ö£¬¹©¶ÁÕ߲ο¼¡£]ÈËÃÇÒ»°ã²»Ì«¿ÉÄÜд³öÏñÕâÑùµÄ´úÂ룺

	int* p = &i;
	int p1 = p;	// error: int initialized by int*

Èç¹ûÕæµÄÓÐÈËÕâÑùд£¬±àÒëÆ÷Ò²²»»áͬÒ⡪¡ªËü»á±¨´íµÄ¡£

ÿµ±´ïµ½Ä³ÖÖÄ¿µÄÓÐÁ½ÌõÒÔÉÏ;¾¶£¬¾Í»áÓÐЩÈ˱»¸ãºýÍ¿£»Ã¿µ±Ò»Ð©Ñ¡ÔñÊdzöÓÚ¸öÈËϲºÃ£¬ÕùÂ۾ͻáÎÞÐÝÎÞÖ¹¡£¼á³ÖÒ»´ÎÖ»ÉùÃ÷Ò»¸öÖ¸Õë²¢ÔÚÉùÃ÷ʱ˳±ã³õʼ»¯£¬À§ÈÅÎÒÃÇÒѾõĻìÏýÖ®Ô´¾Í»áËæ·çÊÅÈ¥¡£Èç¹ûÄãÏëÁ˽âÓйØCµÄÉùÃ÷Óï·¨µÄ¸ü¶àÌÖÂÛ£¬²Î¼û¡¶The Design and Evolution of C++¡· ¡£

Q: ºÎÖÖ´úÂë²¼¾Ö·ç¸ñΪ¼Ñ£¿

A: Ŷ£¬ÕâÊǸöÈËÆ·Î¶ÎÊÌâÁË¡£ÈËÃdz£³£ºÜÖØÊÓ´úÂë²¼¾ÖÖ®·ç¸ñ£¬µ«»òÐí·ç¸ñµÄÒ»ÖÂÐÔÒª±ÈÑ¡ÔñºÎÖÖ·ç¸ñ¸üÖØÒª¡£Èç¹û·ÇÒªÎÒΪÎҵĸöÈËÆ«ºÃ½¨Á¢¡°Âß¼­Ö¤Ã÷¡±£¬ºÍ±ðÈËÒ»Ñù£¬ÎÒ»áÍ·´óµÄ :O)

ÎÒ¸öÈËϲ»¶Ê¹Óá°K&R¡±·ç¸ñ£¬Èç¹ûËãÉÏÄÇЩCÓïÑÔÖв»´æÔڵĹ¹Ôì֮ʹÓùßÀý£¬ÄÇôÈËÃÇÓÐʱҲ³ÆÖ®Îª¡°Stroustrup¡±·ç¸ñ¡£ÀýÈ磺

	class C : public B {
	public:
		// ...
	};

	void f(int* p, int max)
	{
		if (p) {
			// ...
		}
	
		for (int i = 0; i<max; ++i) {
			// ...
		}
	}

ÕâÖÖ·ç¸ñ±È½Ï½ÚÊ¡¡°´¹Ö±¿Õ¼ä¡±¡ª¡ªÎÒϲ»¶Èþ¡Á¿¶àµÄÄÚÈÝ¿ÉÒÔÏÔʾÔÚÒ»ÆÁÉÏ :O) ¶øº¯Êý¶¨Ò忪ʼµÄ»¨À¨ºÅÖ®ËùÒÔÈç´Ë·ÅÖã¬ÊÇÒòΪÕâÑùÒ»À´¾ÍºÍÀඨÒåÇø·Ö¿ªÀ´£¬ÎҾͿÉÒÔÒ»ÑÛ¿´³ö£ºàÞ£¬ÕâÊǺ¯Êý£¡

ÕýÈ·µÄËõ½ø·Ç³£ÖØÒª¡£

һЩÉè¼ÆÎÊÌ⣬±ÈÈçʹÓóéÏóÀàÀ´±íÊ¾ÖØÒªµÄ½çÃæ¡¢Ê¹ÓÃÄ£°åÀ´±íʾÁé»î¶ø¿ÉÀ©Õ¹µÄÀàÐͰ²È«³éÏó¡¢ÕýȷʹÓá°Òì³£¡±À´±íʾ´íÎó£¬Ô¶Ô¶Òª±È´úÂë·ç¸ñÖØÒª¡£

[Òë×¢£º¡¶The Practice of Programming¡·ÖÐÓÐÒ»Õ¶ԡ°´úÂë·ç¸ñ¡±ÎÊÌâ×÷ÁËÏêϸµÄ²ûÊö¡£]

Q: ÎҸðÑconstдÔÚÀàÐÍÇ°Ãæ»¹ÊǺóÃæ£¿

A: ÎÒÊÇϲ»¶Ð´ÔÚÇ°ÃæµÄ¡£²»¹ýÕâÖ»ÊǸöÈË¿ÚζµÄÎÊÌâ¡£¡°const T¡±ºÍ¡°T const¡±¾ùÊÇÔÊÐíµÄ£¬¶øÇÒËüÃÇÊǵȼ۵ġ£ÀýÈ磺

	const int a = 1;	// ok
	int const b = 2;	// also ok

ÎÒÏ룬ʹÓõÚÒ»ÖÖд·¨¸üºÏºõÓïÑÔϰ¹ß£¬±È½Ï²»ÈÝÒ×ÈÃÈËÃÔ»ó :O)

Ϊʲô»áÕâÑù£¿µ±ÎÒ·¢Ã÷¡°const¡±£¨×îÔçÊDZ»ÃüÃûΪ¡°readonly¡±ÇÒÓÐÒ»¸ö½Ð¡°writeonly¡±µÄ¶ÔÓ¦Îʱ£¬ÎÒÈÃËüÔÚÇ°ÃæºÍºóÃæ¶¼ÐУ¬ÒòΪÕâ²»»á´øÀ´¶þÒåÐÔ¡£µ±Ê±µÄC/C++±àÒëÆ÷¶ÔÐÞÊηûºÜÉÙÓÐÇ¿¼ÓµÄÓïÐò¹æÔò¡£

ÎÒ²»¼ÇµÃµ±Ê±Óйýʲô¹ØÓÚÓïÐòµÄÉî˼ÊìÂÇ»òÏà¹ØµÄÕùÂÛ¡£Ò»Ð©ÔçÆÚµÄC++ʹÓÃÕߣ¨ÌرðÊÇÎÒ£©µ±Ê±Ö»Êǵ¥´¿µØ¾õµÃconst int c = 10;Òª±Èint const c = 10;ºÃ¿´¶øÒÑ¡£»òÐí£¬ÎÒÊÇÊÜÁËÕâ¼þÊÂʵµÄÓ°Ï죺Ðí¶àÎÒÔçÄêдµÄÀý×ÓÊÇÓá°readonly¡±ÐÞÊε쬶øreadonly int c = 10;ȷʵ¿´ÉÏÈ¥Òª±Èint readonly c = 10;Êæ·þ¡£¶ø×îÔçµÄʹÓá°const¡±µÄC/C++´úÂëÊÇÎÒÓÃÈ«¾Ö²éÕÒÌæ»»¹¦ÄܰÑreadonly»»³Éconst¶øÀ´µÄ¡£ÎÒ»¹¼ÇµÃºÍ¼¸¸öÈËÌÖÂÛ¹ý¹ØÓÚÓï·¨¡°±äÌ塱ÎÊÌ⣬°üÀ¨Dennis Ritchie¡£²»¹ýÎÒ²»¼ÇµÃµ±Ê±ÎÒÃÇ̸µÄÊÇÄļ¸ÖÖÓïÑÔÁË¡£

ÁíÍ⣬Çë×¢Ò⣺Èç¹ûÖ¸Õë±¾Éí²»¿É±»Ð޸ģ¬ÄÇôconstÓ¦¸Ã·ÅÔÚ¡°*¡±µÄºóÃæ¡£ÀýÈ磺

	int *const p1 = q;	// constant pointer to int variable
	int const* p2 = q;	// pointer to constant int
	const int* p3 = q;	// pointer to constant int
Q: ºêÓÐʲô²»ºÃÂð£¿

A: ºê²»×ñÑ­C++µÄ×÷ÓÃÓòºÍÀàÐ͹æÔò£¬Õâ»á´øÀ´Ðí¶àÂé·³¡£Òò´Ë£¬C++ÌṩÁËÄܺÍÓïÑÔÆäËü²¿·Ö¡°ºÏ×÷Óä¿ì¡±µÄÌæ´ú»úÖÆ£¬±ÈÈçÄÚÁªº¯Êý¡¢Ä£°å¡¢Ãû×Ö¿Õ¼ä»úÖÆ¡£ÈÃÎÒÃÇÀ´¿´ÕâÑùµÄ´úÂ룺

	#include "someheader.h"
struct S {
  int alpha;
  int beta;
 };

Èç¹ûÓÐÈË(²»Ã÷ÖǵØ)дÁËÒ»¸ö½Ð¡°alpha¡±»òÕß¡°beta¡±µÄºê£¬ÄÇôÕâ¶Î´úÂëÎÞ·¨Í¨¹ý±àÒ룬ÉõÖÁ¿ÉÄܸüÔ㡪¡ª±àÒë³öһЩÄãÎ´ÔøÔ¤ÁϵĽá¹û¡£±È·½Ëµ£ºÈç¹û¡°someheader.h¡±°üº¬ÁËÈç϶¨Ò壺
	#define alpha 'a'
	#define beta b[2]
ÄÇÃ´Ç°ÃæµÄ´úÂë¾ÍÍêÈ«±³Àë±¾ÒâÁË¡£

°Ñºê£¨¶øÇÒÖ»Óк꣩µÄÃû³ÆÈ«²¿Óôóд×Öĸ±íʾȷʵÓÐÖúÓÚ»º½âÎÊÌ⣬µ«ºêÊÇûÓÐÓïÑÔ¼¶±£»¤»úÖÆµÄ¡£ÀýÈ磬ÔÚÒÔÉÏÀý×ÓÖÐalphaºÍbetaÔÚSµÄ×÷ÓÃÓòÖУ¬ÊÇSµÄ³ÉÔ±±äÁ¿£¬µ«Õâ¶ÔÓÚºêºÁÎÞÓ°Ïì¡£ºêµÄÕ¹¿ªÊÇÔÚ±àÒëǰ½øÐеģ¬Õ¹¿ª³ÌÐòÖ»ÊǰÑÔ´Îļþ¿´×÷×Ö·ûÁ÷¶øÒÑ¡£ÕâÒ²ÊÇC/C++³ÌÐòÉè¼Æ»·¾³µÄǷȱ֮´¦£º¼ÆËã»úºÍµçÄÔÑÛÖеÄÔ´ÎļþµÄº­ÒåÊDz»Í¬µÄ¡£

²»ÐÒµÄÊÇ£¬ÄãÎÞ·¨È·±£ÆäËû³ÌÐòÔ±²»·¸ÄãËùÈÏΪµÄ¡°ÓÞ´ÀµÄ¡±´íÎ󡣱ȷ½Ëµ£¬½üÀ´ÓÐÈ˸æËßÎÒ£¬ËûÃÇÓöµ½Ò»¸öº¬¡°goto¡±Óï¾äµÄºê¡£ÎÒ¼ûµ½¹ýÕâÑùµÄ´úÂ룬ҲÌýµ½¹ýÕâÑùµÄÂ۵㡪¡ªÓÐʱºêÖеġ°goto¡±ÊÇÓÐÓõġ£ÀýÈ磺

	#define prefix get_ready(); int ret__
	#define Return(i) ret__=i; do_something(); goto exit
	#define suffix exit: cleanup(); return ret__

	void f()
	{
		prefix;
		// ...
		Return(10);
		// ...
		Return(x++);
		//...
		suffix;
	}

Èç¹ûÄãÊÇÒ»¸ö¸ºÔðά»¤µÄ³ÌÐòÔ±£¬ÕâÑùµÄ´úÂë±»Ìá½»µ½ÄãÃæÇ°£¬¶øºê¶¨Ò壨ΪÁ˸øÕâ¸ö¡°Ï··¨¡±Ôö¼ÓÄѶȶø£©±»²Øµ½ÁËÒ»¸öÍ·ÎļþÖУ¨ÕâÖÖÇé¿ö²¢·Çº±¼û£©£¬Äã×÷ºÎ¸ÐÏ룿ÊDz»ÊÇһͷÎíË®£¿

Ò»¸ö³£¼û¶øÎ¢ÃîµÄÎÊÌâÊÇ£¬º¯Êý·ç¸ñµÄºê²»×ñÊØº¯Êý²ÎÊýµ÷ÓùæÔò¡£ÀýÈ磺

	#define square(x) (x*x)

	void f(double d, int i)
	{
		square(d);	// fine
		square(i++);	// ouch: means (i++*i++)
		square(d+1);	// ouch: means (d+1*d+1); that is, (d+d+1)
		// ...
	}

¡°d+1¡±µÄÎÊÌâ¿ÉÒÔͨ¹ý¸øºê¶¨Òå¼ÓÀ¨ºÅ½â¾ö£º

	#define square(x) ((x)*(x))	/* better */

µ«ÊÇ£¬¡°i++¡±±»Ö´ÐÐÁ½´ÎµÄÎÊÌâÈÔȻûÓнâ¾ö¡£

ÎÒÖªµÀÓÐЩ£¨ÆäËüÓïÑÔÖУ©±»³ÆÎª¡°ºê¡±µÄ¶«Î÷²¢²»ÏóC/C++Ô¤´¦ÀíÆ÷Ëù´¦ÀíµÄ¡°ºê¡±ÄÇÑùȱÏݶà¶à¡¢Âé·³ÖØÖØ£¬µ«ÎÒ²¢²»Ïë¸Ä½øC++µÄºê£¬¶øÊǽ¨ÒéÄãÕýȷʹÓÃC++ÓïÑÔÖÐµÄÆäËû»úÖÆ£¬±ÈÈçÄÚÁªº¯Êý¡¢Ä£°å¡¢¹¹Ô캯Êý¡¢Îö¹¹º¯Êý¡¢Òì³£´¦ÀíµÈ¡£ 

[Òë×¢£ºÒÔÉÏÊÇBjarne StroustrupµÄC++ Style and Technique FAQµÄÈ«ÎÄ·­Òë¡£BjarneÊǵ¤ÂóÈË£¬ËûдµÄÓ¢ÎÄÎÄÕ¿ɲ»ºÃ¶Á£¬¼¼ÊõÎÄÕÂÓÈÉõ¡£±¾ÒëÎÄ»òÐí´íÎ󯫯ÄÖ®´¦²»ÉÙ£¬»¶Ó­¹ã´ó¶ÁÕßÖ¸Õý¡£ÎÒµÄemailÊÇ zmelody@sohu.com ¡£]

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4