Search code examples
c++inheritanceinvariants

c++ Assertion failure on return from invariant function


I'm pretty new to C++ so please bear with me...

I'm writing a class that contains a std::string variable which I check if it is a valid C language identifier. The valid identifiers start with "_" or a letter and continue with letters, numbers or _". This class is used by the following classes NamedObject and Foo.

class Name{
    std::string name;
protected:
    virtual bool Inv(void) const{
            if (name[0] >= 'A' && name[0] <= 'Z') return true;
            if (name[0] >= 'a' && name[0] <= 'z') return true;
            if (name[0] == '_')                   return true;
            std::cout << "String input is not a valid identifier."<< std::endl;
            return false;
        }
public:
    Name(){}
    Name(std::string _name) : name(_name){ assert(Inv()); }
    Name(Name& n) : name(n.name) { assert(Inv()); }
    //more constructors and methods
};

class NamedObject{
    Name objectsName;
public:
    //Constructors & Destructor
    NamedObject()          : objectsName(Name()) {}
    NamedObject(Name name) : objectsName(name) {}
    ~NamedObject() {}

    //Accessors-Modifiers
    const Name& Get(void) const { return objectsName; }
    void        Set(const Name name) { objectsName = name; }
};

class Foo : public NamedObject {
public:
    Foo() : NamedObject() {}
    Foo(Name name) : NamedObject(name) {}
    ~Foo();
};

When I try the code:

Name n1("a_1");
Foo *f1 = new Foo(n1);
n1.Set("*a_2");
Foo *f2 = new Foo(n1);

I get the following error: Assertion failed: Inv() line 64 (line of second assert) I have been trying to find the problem with Inv() but didn't come up with anything.


Solution

  • Surely it assert-fails because your "*a_2" string is not a valid name (it doesn't begin with a letter or an underscore).

    If you don't want to assert-fail, then either permit names to begin with an asterisk "*" as well, or use a name that begins with a letter or an underscore.

    (By the way, as pointed out by Walter, you'd be much better off using isalpha() instead of the hacky, non-portable inequality checks against character codes.)