1

just started learning some cpp and got this stuff going:

#include <string>

using std::string;

class Vigenere{
    public:
        Vigenere(string key, string alphabet = "abcdefghijklmnopqrstuvwxyz");
        string encode(string message, string key = _key, string alphabet = _alphabet);
        string decode(string message, string key = _key, string alphabet = _alphabet);


    private:
        string _alphabet;
        string _key;
};

while trying to compile it says "10 [Error] invalid use of non-static data member 'Vigenere::_key'";

line 10 is string Key;

So, is there a way to make it so i can use those variables for each object separately while using them as default arguments?

ARentalTV
  • 344
  • 1
  • 12
  • 1
    How's the compiler supposed to know from which instance to take `Vigenere::_alphabet`? And how would it do it for the first instantion ommiting the argument for that parameter? – LogicStuff Dec 21 '15 at 20:22
  • @LogicStuff The instance the method is called on? Nothing here is static. – Rotem Dec 21 '15 at 20:29
  • 1
    Another thing - [names with a leading underscore](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) are reserved for the implementation in the global namespace. Using them for other things are perhaps not the best idea. – Bo Persson Dec 21 '15 at 20:31
  • @BoPersson if you read the accepted answer to that question, you'll see that an underscore followed by a *lower-case* letter is OK unless it's global, which isn't the case here. Although to stay out of trouble I try to refrain from that habit myself. – Mark Ransom Dec 21 '15 at 20:39
  • @MarkRansom - Yes, I know. However, having the same naming convention for class local and implementation global names takes away some of the advantages of having a convention. – Bo Persson Dec 21 '15 at 20:43
  • I've got more specific error when I ran it in VS2013 Express : "error C2648: 'Vigenere::_alphabet' : use of member as default parameter requires static member" . I think it has an answer in it :) – StahlRat Dec 21 '15 at 20:46

1 Answers1

7

To my knowledge it is not directly possible.

But you can do:

class Vigenere{
    public:
        Vigenere(string key, string alphabet = "abcdefghijklmnopqrstuvwxyz");
        string decode(string message, string key, string alphabet);
        string decode(string message, string key)
        {
           return decode(message, key, _alphabet);
        }
        string decode(string message)
        {
           return decode(message, _key, _alphabet);
        }

        // and same for encode


    private:
        string _alphabet;
        string _key;
};

It takes more source code lines but should give the user of the class the same interface, i.e.

someVigenere.decode("myMessage");          // Use key, alphabet from the object instance
someVigenere.decode("myMessage", "myKey"); // Use alphabet from the object instance
someVigenere.decode("myMessage", "myKey", "myAlphabet"); // Pass all
Support Ukraine
  • 42,271
  • 4
  • 38
  • 63