Make Constructor for Standard Class

  • Thread starter Thread starter TylerH
  • Start date Start date
  • Tags Tags
    Class Standard
Join the discussion
Registration is free. Ask a follow-up in this thread, or start your own.
7 replies · 3K views
TylerH
Messages
729
Reaction score
0
How can I make a constructor for a standard class that accepts my class? For example, I have a class x and I want to make it possible to C++-style cast it to a string (ie "string(x)" rather than "(string)x"); how do I do that/what does the constructor function declaration look like?
 
Physics news on Phys.org
TylerH said:
How can I make a constructor for a standard class that accepts my class? For example, I have a class x and I want to make it possible to C++-style cast it to a string (ie "string(x)" rather than "(string)x"); how do I do that/what does the constructor function declaration look like?

Hey TylerH.

Making non-empty constructors are the same as making default constructors: you just declare another constructor with your parameter list.

As an example:

Code:
#include <string> // Custom string class used as an example 

class MyClass
{
     MyClass(); // Default constructor no arguments
     MyClass(string x); // New constructor takes in string
     virtual ~MyClass();

     string m_mystring;
}

// Default constructor
MyClass::MyClass()
{
   // Blah blah
   m_myString = string();
}

// Custom constructor
MyClass::MyClass(string x)
{
   m_myString = string(x); // Copy string contents
}

// Destructor
MyClass::~MyClass()
{
   // Assume string destructor cleans up everything for string class
}

Also it depends on how you pass the parameter: either by reference (pointer, address) or by value (put the object on the stack).
 
I know how to make a constructor. I'm asking how I make one that allows me to cast my class to a string using C++-style casting, which requires that I somehow make a string constructor that accepts my class as a parameter. However, I don't know how to make a constructor for the string class, since I add my constructor to it's definition, because it's a standard class. (Actually, I could, but that would break the standard-ness and thus, defeat the purpose.)

For example:
Code:
#include <string>

using namespace std;

class X{
public:
     X(string s) : x(s) {} 
     string data()
     {
          return x;
     }
private:
     string x
};

int main()
{
     X t("example"); // I know how to do this.
     string u = string(t); // I want to know how to do this.
     // u should be "example."
     return 0;
}

// This is my attempt. I get an error saying it isn't declared in string.
string::string(const X &x)
{
    *this = x.data();
}
 
Last edited:
I like Serena said:
You can't add constructors to a standard class in C++.

If you want to, you can define your own class that makes use of a standard class, in which you can define custom constructors.

What's the best way to allow my class to be casted to a string?
 
Ah well, you can add a conversion operator to your class.

Code:
class MyClass
{
   operator std::string() const { return x; }
   std::string x;
};

I have learned though that in good programming practices conversion operators should be avoided.
This is due to possibly unexpected type conversions.
Unexpected type conversions are an important pitfall in C++.
For this reason the standard std::string class does not have a conversion operator to a "const char *".
Instead it has a method named c_str().
 
Last edited:
I like Serena said:
Ah well, you can add a conversion operator to your class.

Code:
class MyClass
{
   operator std::string() const { return x; }
   std::string x;
};

I have learned though that in good programming practices conversion operators should be avoided.
This is due to possibly unexpected type conversions.
Unexpected type conversions are an important pitfall in C++.
For this reason the standard std::string class does not have a conversion operator to a "const char *".
Instead it has a method named c_str().
Thanks!

What do you mean "possibly unexpected type conversions"? Could you give an example?

For background, I'm using this in a dictionary library I'm writing. I'm using a trie. I'm using the conversion operator to allow casting from a trie node/dictionary entry to a string. IMHO, it makes sense to allow a dictionary entry to be casted to a string.
 
You're welcome! :smile:

Here's an example of an unexpected conversion:
Code:
#include <iostream>
#include <string>

class MyClass
{
public:
    MyClass(char ch) : m_str(1, ch) {}
    const std::string& toString() const { return m_str; }
private: 
    std::string m_str;
};

int main(void)
{
    MyClass x = 2;
    std::cout << x.toString() << std::endl;
    return 0;
}

Suppose you expected the 2 to be converted to a string.
It didn't.
(What did it do?)

The std::string class is designed to disallow this sort of mistakes.


You seem to have a good justification for using a conversion operator and I would accept that as a code reviewer.

Consider though, whether it really helps your code.
How often does it happen that you need to convert a dictionary entry to a string?
And how bad is it to call a method?

Also note that the conversion operator makes an unnecessary copy of the string, whereas a method like the toString() method in my example can return a const-reference.
(I borrowed the name "toString" from java where that is a standard method.)