|
Thanks Milton..
that works.
Dirk
|
|
|
|
|
Hi Milton,
there is one question left.
Is there a way to convert that bstr into a character string?
So I need a modification also in the other way round.
cheers
Dirk
|
|
|
|
|
Dihirk wrote: convert that bstr into a character string?
sprintf(...) ?!
Maxwell Chen
|
|
|
|
|
Hi Maxwell,
yes, your are right it must be that easy...
I used the wrong format
sprintf (str, "%s", *bstr);
which just resulted in the first character of ther bstr..
correct is
sprintf (str, "%S", *bstr);
Your answer made me sure to look further at the point where I was before.
Thanks
Dirk
|
|
|
|
|
Hi All,
The blocks of code shown below basically do the same thing...
CTest1 c ;<br />
c.Hello() ;
CTest1 *t ;<br />
t = new CTest1() ;<br />
t->Hello() ;<br />
delete t ;<br />
t = NULL ;
They call the Hello() function in CTest1.
My Question is, when should we use them?
What is the advantage of one over the other?
Are there specific instances where one is preferred over the other?
Thanks...
---
With best regards,
A Manchester United Fan
The Genius of a true fool is that he can mess up a foolproof plan!
|
|
|
|
|
In general, dynamic creations of classes (with new and delete) are used in polymorphism (you have a pointer to a base class and you 'create' a pointer to a child class):
CBaseClass
{
};
CChildClass : public CBaseClass
{
};
CBaseClass* pNewClass = new CChildClass;
It is a little bit complicated to explain in details what are the advantages but in brief, it lets you have several pointers to different child classes being used in the same way (as a pointer to the base clase). This is impossible to do without pointers (except by using references but this is another subject )
|
|
|
|
|
This is not a reason to use or not use new - You can still treat a object on the stack polymorphically. For example the following does:
class Base
{
public:
virtual void Message() const = 0;
};
class Derived1
{
public:
virtual void Message() const
{
cout << "Hello from Derived1" << endl;
}
};
class Derived2
{
public:
virtual void Message() const
{
cout << "Hello from Derived2" << endl;
}
};
void PrintMessage(const Base &b)
{
b.Message();
}
void Driver()
{
CDerived1 d1;
CDerived2 d2;
PrintMessage(d1);
PrintMessage(d2);
}
In this example PrintMessage exhibits polymorphic behaviour but there are no new s.
Steve
|
|
|
|
|
TechyMaila wrote: CTest1 c ;
c.Hello() ;
With this technique the object is on the stack. If the object is very large you might not want to put it on the stack - However it is fairly rare for an object to be so big that it comes into the decision process. The main reason you use new to create an object is when you want to control its life time explicitly. For example, if you have an object on the stack and use it like this you're in for problems:
CTest1& Voodoo()
{
CTest1 c;
return c;
}
This is because the object c is destroyed when its scope is exited; in this case when we exit the function the object is destroyed and no longer exists. Thus returning a reference to it is a disastrous mistake.
If you recode the example like this however there is no such problem but you are now responsible for controlling to object's life time:
CTest1* Voodoo()
{
CTest1 *pObject = new CTest1;
return pObject;
}
The programmer must remeber to call delete on the object returned!
Steve
|
|
|
|
|
Thanks a lot for your answers.
So what you are saying is that it is better to use new and delete ? Thanks.
---
With best regards,
A Manchester United Fan
The Genius of a true fool is that he can mess up a foolproof plan!
|
|
|
|
|
TechyMaila wrote: So what you are saying is that it is better to use new and delete? Thanks.
No, I'm not saying that. Here's what I'd say: "Use objects on the stack if you can and new and delete if you have to". It is more efficient (in general) to have objects on the stack; but less flexible. Also if you new an object but forget to delete it you'll leak memory: it's more error prone. In short it depends, for the most part, on the life time requirements of the object.
Steve
|
|
|
|
|
|
In addition to their answers, here is the 3rd reason.
When you declare an object as the data member, you have to include the .H file of the implementation. As:
#include "bar.h"
class foo
{
bar _MyBar;
}; Any changes to the implementation of class bar will cause class foo to be re-compiled again. This is nothing in small projects, but it is quite annoying in large projects. (The case you click [Build] button, you go out to buy a cup of coffee, and you go back 10 minutes later... You see it is still compiling.)
So we would take this way as:
class bar;
class foo
{
bar* _pMyBar;
};
Maxwell Chen
-- modified at 10:24 Saturday 6th May, 2006
|
|
|
|
|
To new , or not to new : that is the question. While your answer is correct I think the question was about the pros and cons of using new vs putting an object on the stack.
Steve
|
|
|
|
|
You should avoid using leading underscores in your code, because it makes it non-portable.
IAW C++ standard, names with leading underscore, are reserved for the implementation.
If you need to use an underscore, use a trialing underscore instead.
----------------------------------------------------------------------------------------
David Maisonave
http://axter.com
Author of Axter's policy based smart pointers
(http://axter.com/smartptr)
|
|
|
|
|
|
Axter wrote: should avoid using leading underscores in your code, because it makes it non-portable.
Please read the language standard specification, ISO/IEC 14882:2003.
The well known non-portable one is '$'.
Axter wrote: a trialing underscore
Huh?
Maxwell Chen
|
|
|
|
|
Is that where all the leading underscores are coming from????
I've been wondering why I've been seeing them more and more lately.
For the record: regarding ANSI specifications, ANSI.org and places like that. I'll be damned if i'm going to pay $291 so I can download a 2MB file of instructions telling me how I'm supposed to name my variables.
If I feel like using m_blahblah...or mixedUpperLower...or lower local and Upper global or whatever then tough.
I've been listening to this grand promise of making code portable for over 20 years now and I've lost count of how many times I've been told we're all doing it wrong.
At least 5 times I've changed to suit some imaginary standard and guess what? As soon as the next new compiler comes out we're told we aren't doing it right and we spend countless hours converting our supposed "portable" code anyway.
If you want to run along with ISO/IEC whatever, more power to you. Have fun and why not? There's nothing wrong with guidelines and doing things consistently (more to make everything readable than anything).
I'll make you a bet that within the next 5 years you'll be programming in a completely different environment, there's a new way and leading underscores are suddenly wrong. I have history on my side.
|
|
|
|
|
Phil C wrote: Is that where all the leading underscores are coming from????
I've been wondering why I've been seeing them more and more lately.
Nothing but just my habbit.
But you may write a letter to Microsoft to ask them: Why _tcstol(...) has that underscore.
You are not obligated to fix in certain naming way as:
m_MyValue;
_MyValue;
mMyValue;
MyValueMember;
ThisIsTheMemberVariableNamedMyValue;
thisismygoddamnmembervariable;
You rule the code. Feel free to name in your own way!
Phil C wrote: I'll be damned if i'm going to pay $291 so I can download a 2MB file of instructions telling me how I'm supposed to name my variables.
Those specifications are not only telling you how to name the variables.
As in this case, ISO/IEC 14882 just enumerates what letters we can use to name identifiers.
Phil C wrote: I've been listening to this grand promise of making code portable for over 20 years now and I've lost count of how many times I've been told we're all doing it wrong.
Yeah. Eight years ago when I was entering the programming field, I was told that C/C++ are the only portable.
The fact?! Not at all.
Phil C wrote: to run along with ISO/IEC
Personally, I don't like reading ISO or ANSI specs. They are written in alien language instead of human understandable English. I only look up in the spec when there is any doubt.
The same idea why you bought a dictionary. Your buying a dictionary not to learn how to write the letters [A ~ Z and a ~ z] but you need to look up the words which you don't know the meanings.
Maxwell Chen
|
|
|
|
|
Maxwell Chen wrote: Nothing but just my habbit.
But you may write a letter to Microsoft to ask them: Why _tcstol(...) has that underscore.
Microsoft is allowed to use leading underscore, because they're considered the implementation.
Leading underscores are reserved for the implementation, which is a cobination of the compiler and the OS.
So Microsoft is allowed to use the leading underscore, but IAW the standard, your own code should not.
One thing Microsoft is doing wrong, is using a leading underscore name followed by a lowercase name that can intrude all namespaces.
Since _tcstol is a macro, it can enter all namespaces.
If Microsoft use _Tcstol instead, then the name is allowed to intrude into all namespaces.
This is not a new standard, and it's been around since the first official C++ standard (1998).
Top ten member of C++ Expert Exchange.
http://www.experts-exchange.com/Cplusplus
|
|
|
|
|
Axter wrote: Microsoft is allowed to use leading underscore, because they're considered the implementation.
Leading underscores are reserved for the implementation, which is a cobination of the compiler and the OS.
So Microsoft is allowed to use the leading underscore, but IAW the standard, your own code should not.
One thing Microsoft is doing wrong, is using a leading underscore name followed by a lowercase name that can intrude all namespaces.
Since _tcstol is a macro, it can enter all namespaces.
If Microsoft use _Tcstol instead, then the name is allowed to intrude into all namespaces.
Section 17.4.3.1.2 in ISO/IEC 14882:2003
1. Certain sets of names and function signatures are always reserved to the implementation:
-- Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
-- Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
Maxwell Chen
|
|
|
|
|
Maxwell Chen wrote: Section 17.4.3.1.2 in ISO/IEC 14882:2003
1. Certain sets of names and function signatures are always reserved to the implementation:
-- Each name that contains a double underscore (__) or begins with an underscore followed by an uppercase letter (2.11) is reserved to the implementation for any use.
-- Each name that begins with an underscore is reserved to the implementation for use as a name in the global namespace.
I'm not sure why you posted the standard.
But I'll explain what the standard is stating, incase you think it contridicts my comment.
The first paragraph is stating that the implementation can use names that are prefxied with double underscore or underscore followed by an uppercase letter for ANY use.
Any use includes using them for MACROS.
#define _T(x) L ## x
That means these types of variables will enter ALL namespaces.
So if you have a local variable called _T, it will not compile if using a header with above macro.
The second paragraph is stating that the implementation can put any name that begins with an underscore inside the global namespace.
FILE * _wfdopen(int, const wchar_t *);
The above function is in the MS header files, and it enters the global namespace, but not local namespace.
So you can create a local variable named _wfdopen, and it will not conflict with the global namespace function.
So IAW C++ standard, it's safe to use a local variable with a leading underscore followed by a lowercase letter.
*** HOWEVER *** some implementations like MS use names with lowercase letters for macros, which means they intrude into all namespaces.
#define _tfdopen _wfdopen
#define _tfsopen _wfsopen
#define _tfopen _wfopen
So my general advise, is to avoid using names that begin with an underscore completely.
And if you feel you have to use an underscore, use a trailing underscore instead.
Example:
int MyFoo_; //Instead of _MyFoo
Top ten member of C++ Expert Exchange.
http://www.experts-exchange.com/Cplusplus
-- modified at 11:59 Sunday 7th May, 2006
|
|
|
|
|
Axter wrote: I'm not sure why you posted the standard.
But I'll explain what the standard is stating, incase you think it contridicts my comment.
Nothing! Just append the statement in the Standard as the reference to what you have said earlier.
And you explained very well!
Maxwell Chen
|
|
|
|
|
Phil C wrote: At least 5 times I've changed to suit some imaginary standard and guess what?
This has been part of the official C++ standard for over 7 years.
Have you been changing it 5 times before the official standard, or after?
Phil C wrote: I'll be damned if i'm going to pay $291 so I can download a 2MB file of instructions telling me how I'm supposed to name my variables.
The original version of the standard doesn't cost that much.
Phil C wrote: I've been listening to this grand promise of making code portable for over 20 years now and I've lost count of how many times I've been told we're all doing it wrong.
The Official C++ standard has not change much since the original standard which is dated 1998.
If you want to avoid changing your code, I recommend you get the standard, so you do it right the first time.
Of course, you're free not to change it, and leave it as-is.
However, I find a lot of developers who complain about having to change their code when a new compiler comes out, are developers who are not following the standard to begin with.
Example:
Before VC++ 7.0 came out, a lot of C++ programmers where using non-standard header (like iostream.h) which never were part of the official C++ standard.
When those developers moved their code from VC++ 6.0 to VC++ 7.0, they suddenly found their code couldn't compile to the new compiler.
Developers can either keep to the standard, and avoid having to change their code, or they can ignore the standard, and enjoy having to revisit their code every time they move their code to a new compiler, or new version of the same compiler.
Top ten member of C++ Expert Exchange.
http://www.experts-exchange.com/Cplusplus
-- modified at 7:21 Sunday 7th May, 2006
|
|
|
|
|
Axter wrote: use a trialing underscore instead
Hi Axter,
Stephen and I are still interested in what a trialing underscore you mentioned is...
Maxwell Chen
|
|
|
|
|
Maxwell Chen wrote: Stephen and I are still interested in what a trialing underscore you mentioned is...
Example:
int MyFoo_; //Instead of _MyFoo
Trailing underscore, meaning put it at the end, instead of the beginning.
Top ten member of C++ Expert Exchange.
http://www.experts-exchange.com/Cplusplus
|
|
|
|