1

I have a class, whose constructor looks like this:

Chunker::Chunker(int chunkSizeX, int chunkSizeY){
    chunkX = chunkSizeX;
    chunkY = chunkSizeY;
}

I would like to offer the user the ability to have either chunkSizeY or chunkSizeX to have a default value (which needs to be calculated by Chunker).

I.E so they might pass in a 'AUTO' keyword or something so that the constructor knows.

Can I do something like:

Chunker::Chunker(int chunkSizeX, char chunkSizeY)

Chunker::Chunker(char chunkSizeX, int chunkSizeY)

Chunker::Chunker(char chunkSizeX, char chunkSizeY)

So that if it gets a char for one or both of the values, it knows to auto-calculate them?

I'm sure their must be a better/standard way I don't know of yet....?

6
  • 2
    Yes, you can do that, no, there is no better way that I know of. What are you asking? Commented Feb 23, 2015 at 16:04
  • What exactly is the problem with the way you describe? Commented Feb 23, 2015 at 16:04
  • I have no problem with it if that is the 'normal' way. I am a relative newbie to c++ and it 'felt' like I wan't doing it in the 'standard' method or perhaps there is a more succinct way? Commented Feb 23, 2015 at 16:06
  • Is casting to int from char a bad plan here? Commented Feb 23, 2015 at 16:06
  • 2
    @Beta No better way? This approach is not very expressive at all and would certainly confuse me. I'd recommend using boost::optional, or alternatively the builder pattern as Paul Evans has described. Another common way to do this is using pointers, where a null pointer represents an omitted argument, but I find that is also not expressive. Commented Feb 23, 2015 at 16:11

4 Answers 4

5

You may use a special empty class to help:

struct Default {};

class Chunker
{
public:
    Chunker(int x, int y) : chunkX(x), chunkY(y) {}
    Chunker(Default, int y) : chunkX(42), chunkY(y) {}
    Chunker(int x, int Default) : chunkX(x), chunkY(42) {}

private:
    int chunkX;
    int chunkY;
};

usage:

Chunker c(1, 2);
Chunker cx(3, Default{});
Chunker cy(Default{}, 4);

or use "static builder"

class Chunker
{
public:
    Chunker(int x, int y) : chunkX(x), chunkY(y) {}
    static Chunker FromX(int x) { return Chunker(x, 42); }
    static Chunker FromY(int y) { return Chunker(42, y); }
private:
    int chunkX;
    int chunkY;
};

usage:

Chunker c(1, 2);
Chunker cx = Chunker::FromX(3);
Chunker cy = Chunker::FromY(4);
Sign up to request clarification or add additional context in comments.

1 Comment

Nice examples, thanks. Quite like the use of static functions.
4

Simply write a helper class that builtds Chunkers, something like:

class MakeChunker {

    void setX(int x) { ...
    void setY(int y) { ...
    Chunker make()

Comments

2

I'd suggest Boost.Optional, which will give you code like this:

void function(optional<int> x, optional<int> y) {
    if (x) {
        // use *x
    }
    if (y) {
        // use *y
    }
}

That said, for the case of constructors, it's sometimes a good idea to add a static factory function in the class:

class Chunker {
    static Chunker create_with_x(int x) {
        ...
    }
    static Chunker create_with_y(int y) {
        ...
    }
};

Comments

0

You can specify multiple constructors in C++ as long as they have different signatures, and the appropriate constructor will be selected by the compiler for each call.

So you can perfectly do :

In Chunker.cpp

Chunker::Chunker(int chunkSizeX, char chunkSizeY) {...} // First constructor
Chunker::Chunker(char chunkSizeX, int chunkSizeY) {...} // Second constructor
Chunker::Chunker(char chunkSizeX, char chunkSizeY) {...} // Third constructor

Then in another file of your program:

Chunker::chunker chunker1 = Chunker::Chunker(1, 'b') // First constructor is used
Chunker::chunker chunker2 = Chunker::Chunker('a', 2) // Second constructor is used
Chunker::chunker chunker3 = Chunker::Chunker('a', 'b') // Third constructor is used

3 Comments

char != const char*
You probably mean 'b', not "b"; dtto for other cases.
The char parameters should not be 'a' or 'b' or anything. OP wanted "AUTO keyword or something". Using explicit and different chars is confusing. Also you should mention implicit conversions (e.g. what happens when the constructor's parameters are size_t and char?)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.