Friday, July 11, 2008

copy constructor

When copies of objects are made

A copy constructor is called whenever a new variable is created from an object. This happens in the following cases (but not in assignment).

  • A variable is declared which is initialized from another object, eg,
    Person q("Mickey"); // constructor is used to build q.
    Person r(p); // copy constructor is used to build r.
    Person p = q; // copy constructor is used to initialize in declaration.
    p = q; // Assignment operator, no constructor or copy constructor.
  • A value parameter is initialized from its corresponding argument.
    f(p);               // copy constructor initializes formal value parameter.
  • An object is returned by a function.

C++ calls a copy constructor to make a copy of an object in each of the above cases. If there is no copy constructor defined for the class, C++ uses the default copy constructor which copies each field, ie, makes a shallow copy.

Don't write a copy constructor if shallow copies are ok

If the object has no pointers to dynamically allocated memory, a shallow copy is probably sufficient. Therefore the default copy constructor, default assignment operator, and default destructor are ok and you don't need to write your own.

If you need a copy constructor, you also need a destructor and operator=

If you need a copy constructor, it's because you need something like a deep copy, or some other management of resources. Thus is is almost certain that you will need a destructor and override the assignment operator.

Copy constructor syntax

The copy constructor takes a reference to a const parameter. It is const to guarantee that the copy constructor doesn't change it, and it is a reference because a value parameter would require making a copy, which would invoke the copy constructor, which would make a copy of its parameter, which would invoke the copy constructor, which ...

Here is an example of a copy constructor for the Point class, which doesn't really need one because the default copy constructor's action of copying fields would work fine, but it shows how it works.

//=== file Point.h =============================================
class Point {
public:
. . .
Point(const Point& p); // copy constructor
. . .
//=== file Point.cpp ==========================================
. . .
Point::Point(const Point& p) {
x = p.x;
y = p.y;
}

. . .
//=== file my_program.cpp ====================================
. . .
Point p; // calls default constructor
Point s = p; // calls copy constructor.
p = s; // assignment, not copy constructor.

Difference between copy constructor and assignment

A copy constructor is used to initialize a newly declared variable from an existing variable. This makes a deep copy like assignment, but it is somewhat simpler:

  1. There is no need to test to see if it is being initialized from itself.
  2. There is no need to clean up (eg, delete) an existing value (there is none).
  3. A reference to itself is not returned.
http://www.fredosaurus.com/

Thursday, July 10, 2008

Console

http://sourceforge.net/projects/console/

Wednesday, July 9, 2008

Deep Copy and Shallow Copy

The terms "deep copy" and "shallow copy" refer to the way objects are copied, for example, during the invocation of a copy constructor or assignment operator. In a deep copy (also called "memberwise copy"), the copy operation respects object semantics. For example, copying an object that has a member of type std::string ensures that the corresponding std::string in the target object is copy-constructed by the copy constructor of class std::string.

class A
{
string s;
};
A a;
A b;
a=b; //deep copy

When assigning b to a, the compiler-generated assignment operator of class A first invokes the assignment operator of class std::string. Thus, a.s and b.s are well-defined, and they are probably not binary-identical. On the other hand, a shallow copy (also called "bitwise copy") simply copies chunks of memory from one location to another. A memcpy() operation is an example of a shallow copy. Because memcpy() does not respect object semantics, it will not invoke the copy constructor of an object. Therefore, you should never use memcpy() to copy objects. Use it only when copying POD (Plain Old Data) types: ints, floating point numbers, and dumb structs.

-------------

A shallow copy of an object copies all of the member field values. This works well if the fields are values, but may not be what you want for fields that point to dynamically allocated memory. The pointer will be copied. but the memory it points to will not be copied -- the field in both the original object and the copy will then point to the same dynamically allocated memory, which is not usually what you want. The default copy constructor and assignment operator make shallow copies.

A deep copy copies all fields, and makes copies of dynamically allocated memory pointed to by the fields. To make a deep copy, you must write a copy constructor and overload the assignment operator, otherwise the copy will point to the original, with disasterous consequences.


NOTE:

there is no const qualifier in the passed parameter of the copy constructor and overloaded assignment operator.


Stack unwinding

Stack unwinding (C++ only)

When an exception is thrown and control passes from a try block to a handler, the C++ run time calls destructors for all automatic objects constructed since the beginning of the try block. This process is called stack unwinding. The automatic objects are destroyed in reverse order of their construction. (Automatic objects are local objects that have been declared auto or register, or not declared static or extern. An automatic object x is deleted whenever the program exits the block in which x is declared.)

If an exception is thrown during construction of an object consisting of subobjects or array elements, destructors are only called for those subobjects or array elements successfully constructed before the exception was thrown. A destructor for a local static object will only be called if the object was successfully constructed.

If during stack unwinding a destructor throws an exception and that exception is not handled, the terminate() function is called. The following example demonstrates this:

#include 
using namespace std;

struct E {
const char* message;
E(const char* arg) : message(arg) { }
};

void my_terminate() {
cout << "Call to my_terminate" << endl;
};

struct A {
A() { cout << "In constructor of A" << endl; }
~A() {
cout << "In destructor of A" << endl;
throw E("Exception thrown in ~A()");
}
};

struct B {
B() { cout << "In constructor of B" << endl; }
~B() { cout << "In destructor of B" << endl; }
};

int main() {
set_terminate(my_terminate);

try {
cout << "In try block" << endl;
A a;
B b;
throw("Exception thrown in try block of main()");
}
catch (const char* e) {
cout << "Exception: " << e << endl;
}
catch (...) {
cout << "Some exception caught in main()" << endl;
}

cout << "Resume execution of main()" << endl;
}

The following is the output of the above example:

In try block
In constructor of A
In constructor of B
In destructor of B
In destructor of A
Call to my_terminate

In the try block, two automatic objects are created: a and b. The try block throws an exception of type const char*. The handler catch (const char* e) catches this exception. The C++ run time unwinds the stack, calling the destructors for a and b in reverse order of their construction. The destructor for a throws an exception. Since there is no handler in the program that can handle this exception, the C++ run time calls terminate(). (The function terminate() calls the function specified as the argument to set_terminate(). In this example, terminate() has been specified to call my_terminate().)

http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/cplr155.htm

Tuesday, July 8, 2008

Smart Pointers

Modern C++ Design Chapter 7

Thursday, July 3, 2008

下载流媒体的四种小技巧

第一、首先尝试着打开IE浏览窗口中的查看菜单项,执行下拉菜单中的“源文件”命令,随后在弹出的“记事本”编辑界面中,依次执行“编辑”/“查找”命令,在查找对话框中,可以输入流媒体协议的名称,例如RTSP、MMS、PNM以及MMST协议,这样就可能获得流媒体文件的真实下载地址了;不过,这种方法只适用没有采用屏蔽技术的网站,要是无法打开“源文件”,可以使用下面的技巧。

第二、要是在线播放流媒体信息时,系统自动调出Windows媒体播放器时,你可以用鼠标右键单击播放窗口,执行快捷菜单中的“属性”命令,打开该属性界面中的“文件”标签页面,在对应的页面中,我们就能清楚地看到流媒体文件的真实下载地址了,此时将该地址粘贴到专用下载工具中就可以了。  

第三、用鼠标右键单击网页中的某个流媒体链接地址时,也许你会在随后打开的右键菜单中,看到“目标另存为”这样的命令,执行该命令后,你就能将该流媒体链接地址保存为HTML文件,用记事本打开该html文件,你就能方便地找到流媒体文件的真实下载地址了。

第四、要是单击某个网页中的流媒体下载链接时,IE浏览器能很快地将百十兆左右的流媒体文件,下载下来,但发现下载获得的文件大小只有几十KB,那么这个文件很有可能是RAMASFWMA或ASX格式的;其实该文件,只是起导航作用,此时你可以用记事本将它们打开,也许真实的下载地址就“躺”在其中呢。

两款探查真实下载地址的软件-Project URL Snooper和Asp2url最新版 (下载高手之必备之利器)

Project URL Snooper 是一个网络信息侦测(嗅探)软件, 能够实时跟踪通过你电脑中(经过网卡,调制解调器等)的数据信息,并分析出里面的各种类型的URL地址.一些电影点播网站对于影片的地址往往隐藏的很好,但是这个软件能够很容易的将这些地址轻易展现在你的眼前。是用来配合Streambox VCR, ASFR ,SDP 等一些流行的流媒体下载软件很好的助手。

Project URL Snooper (free URL Snooper software download)

Project URL Snooper (Freeware/Windows)

Many links to streaming audio and video that you come across on the web are hidden behind JavaScript, Macromedia Flash, ActiveX. Because of this, it is sometimes very difficult to figure out the actual urls that correspond to the streams being played.

Project URL Snooper was written to help users locate the urls of audio and video files so that they can be recorded.

The goal of Project URL Snooper is to provide a one-stop easy solution to finding the URLs for all streams. It does this by watching network traffic and identifying potential urls, especially streaming media urls.

Platform: Windows 9x/2K/XP.

Screenshot: Project URL Snooper - free URL Snooper software

New Features in Project URL Snooper version 2:

  • Totally revamped and cleaner user interface.
  • Smart packet spanning - rebuilds packet streams to eliminate split-urls.
  • Improved identification of protocols, duplicates, and url arguments.
  • New dynamic url filtering keywords.
  • Improved context menu support, drag and drop file searching.
  • Includes recording hints and website links.
  • User customizable browser selection and favorites menu.
Brief Project URL Snooper Instructions for Fast Learners!
To find the hidden url for a streaming audio/video file:
  • Open your browser and go to the page containing the stream you are interested in.
  • Start Project Url Snooper and click on "Sniff Network."
  • Go to the browser and start the stream playing.
  • Hopefully you will soon see the stream URLs appear in the Results List.
  • After the stream begins playing, you may stop it.
  • Drag URLs to targets, or right-click to copy to clipboard or launch 3rd party apps.

Tuesday, July 1, 2008

Binary Search

l = 0, u = n-1

loop

if l > u
p = -1; break
m = (l+u)/2
case
x[m] < t: l=m+1
x[m] == t: p=m; break
x[m] > t: u = m-1