The c++ way?

J

JustSomeGuy

I have a data structure that contains a buffer of character of lenght n.

The buffer in this case contains a string that is not null terminated.

at the moment to get a null terminated buffer I'm doing the following:

strncpy(buf, (const char *)data, n);
buf[n] = '\0';
string x(buf);

Surely there must be a better way to initialze the string x...

By the way is there such a thing as a Variant in C++ as there is in
Visual Basic?
 
A

Alf P. Steinbach

* JustSomeGuy:
I have a data structure that contains a buffer of character of lenght n.

The buffer in this case contains a string that is not null terminated.

at the moment to get a null terminated buffer I'm doing the following:

strncpy(buf, (const char *)data, n);
buf[n] = '\0';
string x(buf);

Surely there must be a better way to initialze the string x...


Off the cuff,

string x( data, data+n );

By the way is there such a thing as a Variant in C++ as there is in
Visual Basic?

Not in the language or its standard library, but there is something like
it in the Boost library.

However, if you're smart you'll register for a mindwipe for the VB parts
of your brain -- it's not a good idea to adopt such practices in C++.
 
J

JKop

JustSomeGuy posted:
By the way is there such a thing as a Variant in C++ as there is in
Visual Basic?


Here is how the Variant type in VB works:


class Variant
{
private:

enum
{
intE,
charE,
doubleE
} current_type;

union
{
int intD;
char charD;
double doubleD;
} data;

public:
//Assignment operator goes here, as well as other operators
};



As you can see, Variant's are slow, and waste more memory. It's a lose-lose
situation, but then again if you're one of those "Visual Basic, Dumb it
Down" people, you may take a shine to it!


-JKop
 
P

Phlip

JustSomeGuy said:
I have a data structure that contains a buffer of character of lenght n.

The buffer in this case contains a string that is not null terminated.

at the moment to get a null terminated buffer I'm doing the following:

strncpy(buf, (const char *)data, n);
buf[n] = '\0';
string x(buf);

Surely there must be a better way to initialze the string x...

Yes. You put the above into a method of your data structure, and always call
that function when you need the string. Then, if the string representation
ever changes, you only have one place to upgrade.

But there might be a way using std::copy or similar. Others will reply about
that.
By the way is there such a thing as a Variant in C++ as there is in
Visual Basic?

Yes. MS renamed VB's plugin layer "COM", and published the Variant as the
low-level type VARIANT. In C++ the high level type _variant_t wraps that.

For a portable solution, go to www.boost.org and look at boost::any.
 
P

Phlip

Alf said:
Not in the language or its standard library, but there is something like
it in the Boost library.

However, if you're smart you'll register for a mindwipe for the VB parts
of your brain -- it's not a good idea to adopt such practices in C++.

Except when you occassionally need the Variable State Pattern from
/Smalltalk Best Practice Patterns/...
 
K

Kevin Saff

JustSomeGuy said:
I have a data structure that contains a buffer of character of lenght n.

The buffer in this case contains a string that is not null terminated.

at the moment to get a null terminated buffer I'm doing the following:

strncpy(buf, (const char *)data, n);
buf[n] = '\0';
string x(buf);

Surely there must be a better way to initialze the string x...

This works:

std::string x (data, n);

It constructs the string from the first n chars in data.
By the way is there such a thing as a Variant in C++ as there is in
Visual Basic?

There are different ideas of what a variant should do. Boost
http://www.boost.org has a couple different implementations, but they don't
act like VB's. Since you can overload operators, it might not be too much
trouble to make one, depending on what exactly you need.

HTH
 
J

JustSomeGuy

JKop said:
JustSomeGuy posted:


Here is how the Variant type in VB works:

class Variant
{
private:

enum
{
intE,
charE,
doubleE
} current_type;

union
{
int intD;
char charD;
double doubleD;
} data;

public:
//Assignment operator goes here, as well as other operators
};

As you can see, Variant's are slow, and waste more memory. It's a lose-lose
situation, but then again if you're one of those "Visual Basic, Dumb it
Down" people, you may take a shine to it!

-JKop

Of course!
A question though....

In the public section I guess I can't add these...

int Get(void);
char Get(void);
double Get(void);

because the return type is not considered to be part of the signature...
I guess however that I could do...

void Get(int &x)
void Get(char &x)
void Get(double &x)


But i think you are talking about operator= is that right?
 
A

Alan Johnson

JKop said:
JustSomeGuy posted:





Here is how the Variant type in VB works:


class Variant
{
private:

enum
{
intE,
charE,
doubleE
} current_type;

union
{
int intD;
char charD;
double doubleD;
} data;

public:
//Assignment operator goes here, as well as other operators
};



As you can see, Variant's are slow, and waste more memory. It's a lose-lose
situation, but then again if you're one of those "Visual Basic, Dumb it
Down" people, you may take a shine to it!


-JKop


Semi-OT:
That captures the basic idea, though the VARIANT structure from COM
Automation (which, unless I misunderstand, is the same thing VB uses for
a Variant), is actually quite a bit more complex. See link for details:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap6_7zdz.asp

Alan
 
J

JKop

JustSomeGuy posted:
Of course!
A question though....

In the public section I guess I can't add these...

int Get(void);
char Get(void);
double Get(void);

because the return type is not considered to be part of the
signature... I guess however that I could do...

void Get(int &x)
void Get(char &x)
void Get(double &x)


But i think you are talking about operator= is that right?


In the above, you are using an actual member function to get the data.
Consider the following function:


void TakeNumber(int in_number);


Here's how *your* idea would work:

int main(void)
{
Variant j;

// ...

TakeNumber( j.GetInt() );

//or something like that

}


What I had in mind was actually declaring a "cast operator", so that you
could simply do the following:


int main(void)
{
Variant j;

// ...

TakeNumber(j);

TakeCharachter(j);

TakeDouble(j);
}


The cast operator would be defined as so:


Variant::eek:perator int(void)
{
if (current_type == intE)
{
return data.intD;
}
else
{
throw "poo!";
}
}

Variant::eek:perator double(void)
{
if (current_type == doubleE)
{
return data.doubleD;
}
else
{
throw "poo!";
}
}


Or something along those lines!


-JKop
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,169
Messages
2,570,920
Members
47,464
Latest member
Bobbylenly

Latest Threads

Top