By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
458,146 Members | 1,631 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 458,146 IT Pros & Developers. It's quick & easy.

About the return type of the function !

P: n/a
Aff
Brothers ,
i am facing a problem which is as follow:

class poly
{
private:
char name[20];
int capacity;
public:
poly(char [], int );
char* gettername();

};

poly::poly(char a[],int cap)
{
int counter=0;
counter=strlen(a);
for(int i=0;i<counter;i++)
{
name[i]=a[i];
}

}
char* poly::gettername()
{
// here i want to return the name which is stored in the char
array(private data) .which is best way ?to do so ..and explain the
reason of doing such thing .

}

int main()
{

return 0;
}

Oct 14 '06 #1
Share this Question
Share on Google+
12 Replies


P: n/a
Aff@n wrote:
Brothers ,
i am facing a problem which is as follow:

class poly
{
private:
char name[20];
Why are you using fixed length char buffer instead of std::string?
int capacity;
public:
poly(char [], int );
char* gettername();

};

poly::poly(char a[],int cap)
{
int counter=0;
counter=strlen(a);
strlen() returns a size_t, it would be bettert to make counter that
type.
for(int i=0;i<counter;i++)
{
name[i]=a[i];
}
This fails to copy the null terminator. That's probably not what you
want if your intent is to have C-style strings.
}
char* poly::gettername()
{
// here i want to return the name which is stored in the char
array(private data) .which is best way ?
There is no best way. What's the point of having it private it you
provide an accessor?

Without knowing what your overall design goals are, it's impossible to
answer the question.
A tentative reply is dump the buffer, use std::string, either return a
copy as needed or move the code that needs the access to the member
into the class.


Brian
Oct 14 '06 #2

P: n/a

Aff@n wrote:
Brothers ,
i am facing a problem which is as follow:

class poly
{
private:
char name[20];
int capacity;
public:
poly(char [], int );
char* gettername();

};

poly::poly(char a[],int cap)
{
int counter=0;
counter=strlen(a);
for(int i=0;i<counter;i++)
{
name[i]=a[i];
}

}
char* poly::gettername()
{
// here i want to return the name which is stored in the char
array(private data) .which is best way ?to do so ..and explain the
reason of doing such thing .

}

int main()
{

return 0;
}
todo the best 1st make an other object which will not break
encapsulation,
char* poly::gettername()
{
char *temp;
temp = new char [20];
strcpy(temp,name);
return temp;// this will not destroy the memory untill destroyed so u
have to be carefull usning dat.
}

Oct 14 '06 #3

P: n/a
"Aff@n" <af********@gmail.comwrote in message
news:11**********************@k70g2000cwa.googlegr oups.com...
Brothers ,
i am facing a problem which is as follow:

class poly
{
private:
char name[20];
int capacity;
public:
poly(char [], int );
char* gettername();

};

poly::poly(char a[],int cap)
{
int counter=0;
counter=strlen(a);
for(int i=0;i<counter;i++)
{
name[i]=a[i];
}

}
char* poly::gettername()
{
// here i want to return the name which is stored in the char
array(private data) .which is best way ?to do so ..and explain the
reason of doing such thing .

}

int main()
{

return 0;
}
This is one of the problems for which std::string was designed. Just make
name a std::string and return it and your problem goes away.

class poly
(
private:
std::string name;
int capacity;
public:
poly( std::string&, int );
std::string gettername();
};

poly::poly( std::string a, int cap )
{
name = a;
}

std::string poly::gettername ()
{
return name;
}

Is there any reason you are not using std::string? And you can even use
c-style strings to initialize it. I.E.

poly MyInstance( "This Name", 10 );
Oct 14 '06 #4

P: n/a
>
todo the best 1st make an other object which will not break
encapsulation,
char* poly::gettername()
{
char *temp;
temp = new char [20];
strcpy(temp,name);
return temp;// this will not destroy the memory untill destroyed so u
have to be carefull usning dat.
}
No! Don't do this. It is (1) dangerous and (2) inconvenient and (3)
inefficient.

Dangerous because the user have to manually delete the pointer.

Inconvenient because the call cannot be inside an expression:

ploy obj("Hello", 5);
cout << obj.gettername(); // Oops, you have a memory leak!

Inefficient because you have to allocate and deallocate memory, you have
to do copying and counting etc.

So instead, do what many have suggested--use std::string and return a
const reference, or simply return a const pointer:

class poly
{
char name[20];

public:
const char* gettername() const
{
return name;
}

// ...
};

Oct 14 '06 #5

P: n/a

Aff@n wrote:
Brothers ,
i am facing a problem which is as follow:
The class name chosen here is inadequate, it would have been much
simpler to explain this issue if you had used something more relevent.
class poly
{
private:
char name[20];
int capacity;
public:
poly(char [], int );
char* gettername();

};

poly::poly(char a[],int cap)
{
int counter=0;
counter=strlen(a);
for(int i=0;i<counter;i++)
{
name[i]=a[i];
}

}
char* poly::gettername()
{
// here i want to return the name which is stored in the char
array(private data) .which is best way ?to do so ..and explain the
reason of doing such thing .

}

int main()
{

return 0;
}
Doing the above with a std::string is so much easier because no
pointers of any kind are needed as far as the programmer is concerned.
Pointers == bugs and arrays are evil (specially char arrays).

What pointers do in the case of a char* is HIDE the fact thats its not
a pointer to a single character but a pointer to an array of characters
that is being accessed. Also, you have no choice but accept the fact
that a space may be inserted in that char array (something a
std::string takes with no problem). hence, you must provide the length
of the string to be stored in your ctor (yes...more bad news).

In order to properly store a character array, you need to dynamically
allocate the incoming array using a member pointer. And you need to
protect that pointer by declaring get() as a const member function or
you will be dealing with nasty side effects (where some idiot uses the
get() function to reset the internal pointer). Not good, very nasty.

I'm not done yet. Copying an instance of a class like poly requires
special considerations. You have no choice but to hard-code a copy ctor
in order to allocate a new array and hence set the critical member
pointer. A std::string member would have copied automatically because a
std::string already has its own copy ctor, unlike a char[] which
doesn't know what a copy ctor is.
Wait, we haven't discussed assignment yet... lets disable it for now.

Are you getting the drift? Pointers and Arrays means much more work and
a lot more code, not to mention special considrations.
Incidentally, in the code below: the type unsigned (integer) should be
replaced with size_t, we'll ignore that for now. Also, you have to
verify that your compiler inserts the null terminator when:
const char a[] = "a short string with spaces"; // verify the str length
output below

#include <iostream>

class poly
{
char* p_name;
public:
poly( const char*, unsigned length );
poly(const poly& copy);
~poly();
poly& operator=(const poly& rhv); // disabled
const char* getStr() const;
};

poly::poly( const char* p_a, unsigned length )
{
std::cout << "length = " << length;
std::cout << std::endl;
p_name = new char[length]; // heap allocation
for(unsigned i = 0; i < length; ++i)
{
p_name[i] = *p_a++;
}
}

poly::poly(const poly& copy)
{
unsigned sz = *copy.p_name;
p_name = new char[sizeof(sz)];
for(unsigned i = 0; i < sz; ++i)
{
p_name[i] = copy.p_name[i];
}
}

poly::~poly()
{
delete [] p_name; // deallocate array
}

const char* poly::getStr() const
{
return p_name;
}

int main()
{
const char a[] = "a short string with spaces";
poly test(a, sizeof(a)); // length is required
std::cout << test.getStr() << std::endl;

poly duplicate = test; // copy test
std::cout << duplicate.getStr() << std::endl;

return 0;
}

/*
length = 27
a short string with spaces <- 26 characters + '/0'
a short string with spaces
*/

Oct 14 '06 #6

P: n/a

Jim Langston wrote:
"Aff@n" <af********@gmail.comwrote in message
news:11**********************@k70g2000cwa.googlegr oups.com...
Brothers ,
i am facing a problem which is as follow:

class poly
{
private:
char name[20];
int capacity;
public:
poly(char [], int );
char* gettername();

};

poly::poly(char a[],int cap)
{
int counter=0;
counter=strlen(a);
for(int i=0;i<counter;i++)
{
name[i]=a[i];
}

}
char* poly::gettername()
{
// here i want to return the name which is stored in the char
array(private data) .which is best way ?to do so ..and explain the
reason of doing such thing .

}

int main()
{

return 0;
}

This is one of the problems for which std::string was designed. Just make
name a std::string and return it and your problem goes away.

class poly
(
private:
std::string name;
int capacity;
public:
poly( std::string&, int );
std::string gettername();
};

poly::poly( std::string a, int cap )
{
name = a;
}

std::string poly::gettername ()
{
return name;
}

Is there any reason you are not using std::string? And you can even use
c-style strings to initialize it. I.E.

poly MyInstance( "This Name", 10 );
I'll second the above.
Allow me to clarify the code or the OP is gonna freak:

class poly
(
std::string name;
public:
poly( std::string );
std::string gettername() const;
};

poly::poly( std::string a ) : name( a )
{
}

std::string poly::gettername() const
{
return name;
}

int main()
{
poly MyInstance("This Name");
std::cout << MyInstance.gettername() << std::endl;
}

Oct 14 '06 #7

P: n/a

Salt_Peter wrote:
Aff@n wrote:
Brothers ,
i am facing a problem which is as follow:

The class name chosen here is inadequate, it would have been much
simpler to explain this issue if you had used something more relevent.
class poly
{
private:
char name[20];
int capacity;
public:
poly(char [], int );
char* gettername();

};

poly::poly(char a[],int cap)
{
int counter=0;
counter=strlen(a);
for(int i=0;i<counter;i++)
{
name[i]=a[i];
}

}
char* poly::gettername()
{
// here i want to return the name which is stored in the char
array(private data) .which is best way ?to do so ..and explain the
reason of doing such thing .

}

int main()
{

return 0;
}

Doing the above with a std::string is so much easier because no
pointers of any kind are needed as far as the programmer is concerned.
Pointers == bugs and arrays are evil (specially char arrays).

What pointers do in the case of a char* is HIDE the fact thats its not
a pointer to a single character but a pointer to an array of characters
that is being accessed. Also, you have no choice but accept the fact
that a space may be inserted in that char array (something a
std::string takes with no problem). hence, you must provide the length
of the string to be stored in your ctor (yes...more bad news).

In order to properly store a character array, you need to dynamically
allocate the incoming array using a member pointer. And you need to
protect that pointer by declaring get() as a const member function or
you will be dealing with nasty side effects (where some idiot uses the
get() function to reset the internal pointer). Not good, very nasty.

I'm not done yet. Copying an instance of a class like poly requires
special considerations. You have no choice but to hard-code a copy ctor
in order to allocate a new array and hence set the critical member
pointer. A std::string member would have copied automatically because a
std::string already has its own copy ctor, unlike a char[] which
doesn't know what a copy ctor is.
Wait, we haven't discussed assignment yet... lets disable it for now.

Are you getting the drift? Pointers and Arrays means much more work and
a lot more code, not to mention special considrations.
Incidentally, in the code below: the type unsigned (integer) should be
replaced with size_t, we'll ignore that for now. Also, you have to
verify that your compiler inserts the null terminator when:
const char a[] = "a short string with spaces"; // verify the str length
output below

#include <iostream>

class poly
{
char* p_name;
public:
poly( const char*, unsigned length );
poly(const poly& copy);
~poly();
poly& operator=(const poly& rhv); // disabled
const char* getStr() const;
};

poly::poly( const char* p_a, unsigned length )
{
std::cout << "length = " << length;
std::cout << std::endl;
p_name = new char[length]; // heap allocation
for(unsigned i = 0; i < length; ++i)
{
p_name[i] = *p_a++;
}
}

poly::poly(const poly& copy)
{
unsigned sz = *copy.p_name;
p_name = new char[sizeof(sz)];
for(unsigned i = 0; i < sz; ++i)
{
p_name[i] = copy.p_name[i];
}
}

poly::~poly()
{
delete [] p_name; // deallocate array
}

const char* poly::getStr() const
{
return p_name;
}

int main()
{
const char a[] = "a short string with spaces";
poly test(a, sizeof(a)); // length is required
std::cout << test.getStr() << std::endl;

poly duplicate = test; // copy test
std::cout << duplicate.getStr() << std::endl;

return 0;
}

/*
length = 27
a short string with spaces <- 26 characters + '/0'
a short string with spaces
*/
And for the record, compare that with a std::string:

class poly
(
std::string name;
public:
poly( std::string );
std::string gettername() const;
};

poly::poly( std::string s ) : name(s)
{
}

std::string poly::gettername() const
{
return name;
}

int main()
{
poly test("a short string with spaces");
std::cout << test.gettername() << std::endl;
poly duplicate = test;
std::cout << duplicate.gettername() << std::endl;
}

Oct 14 '06 #8

P: n/a
And for the record, compare that with a std::string:
>
class poly
(
std::string name;
public:
poly( std::string );
std::string gettername() const;
};

poly::poly( std::string s ) : name(s)
{
}

std::string poly::gettername() const
{
return name;
}
That is fine, but why not returning a const std::string& ?

Ben
Oct 14 '06 #9

P: n/a

"benben" <benhonghatgmaildotcom@nospamwrote in message
news:45***********************@news.optusnet.com.a u...
>poly::poly( std::string s ) : name(s)
{
}

std::string poly::gettername() const
{
return name;
}

That is fine, but why not returning a const std::string& ?
Or having the ctor take const std::string& ?
Oct 14 '06 #10

P: n/a
benben wrote:
And for the record, compare that with a std::string:

class poly
(
that should have been

class poly
{
std::string name;
public:
poly( std::string );
std::string gettername() const;
};

poly::poly( std::string s ) : name(s)
{
}

std::string poly::gettername() const
{
return name;
}

That is fine, but why not returning a const std::string& ?

Ben
of course, why not?
http://www.parashift.com/c++-faq-lit...html#faq-18.11
Note that the result will be the same in either case - a single copy
ctor gets invoked.

const std::string& poly::gettername() const
{
return name;
}

Oct 14 '06 #11

P: n/a
Salt_Peter schrieb:
benben wrote:
>>std::string poly::gettername() const
{
return name;
}
That is fine, but why not returning a const std::string& ?

Ben

of course, why not?
http://www.parashift.com/c++-faq-lit...html#faq-18.11
Note that the result will be the same in either case - a single copy
ctor gets invoked.

const std::string& poly::gettername() const
{
return name;
}
Why should a copy ctor gets called when returning a reference?

poly p;
std::cout << p.gettername();

When returning by value, a temporary is copy-ctored. When returning by
reference, only the reference is returned.

--
Thomas
http://www.netmeister.org/news/learn2quote.html
Oct 14 '06 #12

P: n/a

Thomas J. Gritzan wrote:
Salt_Peter schrieb:
benben wrote:
>std::string poly::gettername() const
{
return name;
}
That is fine, but why not returning a const std::string& ?

Ben
of course, why not?
http://www.parashift.com/c++-faq-lit...html#faq-18.11
Note that the result will be the same in either case - a single copy
ctor gets invoked.

const std::string& poly::gettername() const
{
return name;
}

Why should a copy ctor gets called when returning a reference?

poly p;
std::cout << p.gettername();
Good point.
>
When returning by value, a temporary is copy-ctored. When returning by
reference, only the reference is returned.

--
Thomas
http://www.netmeister.org/news/learn2quote.html
Oct 14 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.