Some Comments on Copy Constructors
A copy constructor is exactly what the name implies : a constructor for an object that is initialized as a copy of another object. In other words it is a constructor for making clones.
If A is a clone of another object B, it means that A should be an exact copy of B and so A should contain member data that are copies of the member data of B. If, in the destructor, any member data of A is destroyed, this must not affect the member data of B.
Programs that invoke copy constructors usually involve STL containers (e.g. vectors, maps, queues, etc). Containers contain clones of objects. Hence the need for copy constructors. This is known as copy semantics. Programs that involve copy semantics usually do not emphasize size efficiency.
Default and Customized Constructors
- A default (no-parameter) constructor is for creating an object with default state.
- That is, with member data set to default values.
- The principle behind this is that (by design) such objects can be used immediately
after creation. - Note that it must make sense to construct an object with default state.
- There are 2 points to note about code like the following : some_class instance;
- This indicates that we want to create an object "instance" of type "some_class"
and that "instance" should have default state. - If it is deemed acceptable
that a "some_class" object, in default state, has member data that can be set to
default values, then it does make sense to have "instance" in default state. - The compiler requires the definition of a default constructor in order to successfully
compile code like the above.
- This indicates that we want to create an object "instance" of type "some_class"
- If there are no constructor functions at all for "some_class", it means that
we want the compiler to create the default constructor for us. This is not always
a good idea because an unsatisfactory constructor may be created for our code. - If we have at least one non-default constructor for "some_class", but no default
constructor for the class, e.g. : some_class(int i); This indicates the following:- That by design a "some_class" object has no default state.
- That in order
to be constructed properly, parameters must be given in order to sensibly initialize
the state of the object. - In the case of "some_class", it means that parameter
"i" is used to somehow initialize an instance to a meaningful state. - In this
case, the compiler will not generate any default constructor for "some_class" because
by design the class must not have one.
Careful to allocate BSTRs using ::SysAllocString().
Note that code like the following :
BSTR bstr = L"My BSTR";
does not allocate a BSTR.
To allocate a BSTR, you must use ::SysAllocString() :
BSTR bstr = ::SysAllocString(L"My BSTR");
Verify this with a call to ::SysStringByteLen() :
UINT uiLen = ::SysStringByteLen(bstr);
In the first case (using merely L), we get uiLen == 0.
In the second case, (using ::SysAllocString()), we get uiLen == 14 (the size of the string "My BSTR" in unicode.
This is because creating a BSTR via ::SysAllocString() generates a proper BSTR with a preceding 4 byte length indicator placed in the memory location just preceding the actual BSTR data.
Code like L"My BSTR" only creates in memory a Unicode string without any preceding 4 byte length indicator.
- Bio.
Some Comments on Copy Constructors
A copy constructor is exactly what the name implies : a constructor for an object that is initialized as a copy of another object. In other words it is a constructor for making clones.
If A is a clone of another object B, it means that A should be an exact copy of B and so A should contain member data that are copies of the member data of B. If, in the destructor, any member data of A is destroyed, this must not affect the member data of B.
Programs that invoke copy constructors usually involve STL containers (e.g. vectors, maps, queues, etc). Containers contain clones of objects. Hence the need for copy constructors. This is known as copy semantics. Programs that involve copy semantics usually do not emphasize size efficiency.
Default and Customized Constructors
- A default (no-parameter) constructor is for creating an object with default state.
1.1. That is, with member data set to default values.
1.2. The principle behind this is that (by design) such objects can be used immediately after creation.
1.3. Note that it must make sense to construct an object with default state.
1.4. There are 2 points to note about code like the following :
- some_class instance;
2.1. This indicates that we want to create an object "instance" of type "some_class" and that "instance" should have default state.
2.2. If it is deemed acceptable that a "some_class" object, in default state, has member data that can be set to default values, then it does make sense to have "instance" in default state.
2.3. The compiler requires the definition of a default constructor in order to successfully compile code like the above.
- If there are no constructor functions at all for "some_class", it means that we want the compiler to create the default constructor for us. This is not always a good idea because an unsatisfactory constructor may be created for our code.
- If we have at least one non-default constructor for "some_class", but no default constructor for the class, e.g. :
some_class(int i);
This indicates the following :
4.1. That by design a "some_class" object has no default state.
4.2. That in order to be constructed properly, parameters must be given in order to sensibly initialize the state of the object.
4.3. In the case of "some_class", it means that parameter "i" is used to somehow initialize an instance to a meaningful state.
4.4. In this case, the compiler will not generate any default constructor for "some_class" because by design the class must not have one.
COM Objects that are created via tags
The following is advise from Brian Muth MVP, taken from the MSDN Forum for Visual C++ Language :
To use the <OBJECT> tag (to create a COM object), the ATL COM object needs to implement the IObjectWithSite interface. This can be done quite trivially, since ATL gives you the IObjectWithSiteImpl<> template. Just add the following line to your list of inherited classes:
public IObjectWithSiteImpl<CMyIeObj>,
and to the BEGIN_COM_MAP table, add:
COM_INTERFACE_ENTRY(IObjectWithSite)
Internet Explorer with Tabs : Debugging a COM Object or an ActiveX inside a Web Page
The following advise is for Internet Explorers that features tabs :
In order to debug a web page for the purpose of stepping into a COM object or an ActiveX created within HTML code, it is not sufficient to simply start iexplore.exe.
This is because the main IE process may spawn additional iexplore.exe for every tab.
Hence one way to debug into a HTML page is as follows :
- Start IE.
- Load the web page.
- Determine the Process ID (PID) of the iexplore.exe that is hosting the web page.
- Debug into the running process of that iexplore.exe by using the "Attach To Process" facility.
- Refresh the web page.
- Bio.