Параметр указателя объекта не может использовать метод доступа из того же класса, что и объект - PullRequest
0 голосов
/ 02 февраля 2012

Итак, у меня есть это:

class A
{
private:
    unsigned int _uid; //user identifier
public:
    A();
    A(const char *, const char *, int, int, const char *, const char *, const char *);
    virtual ~A();
    int getUserID();
};

int A::getUserID(){
    return _uid;
}

//The class UserDB is not that important as this method is at this moment.
void UserDB::adduser(A* newUser){
    if(newUser.getUserID == 0) //Not working, not sure why... Gives syntax error. (1)
    //Something is done if the condition is true;
};

int main(){
    UserDB B
    A tempObj;
    //Assume the 7 following variables have been initialized correctly.
    char uloginName[9];
    char homeDirectory[33];
    int userID;
    int groupID;
    char password[17];
    char shell[17];
    char gecos[65];
    tempObj = new A(uloginName, password, userID, groupID, gecos, homeDirectory, shell);
    B = new UserDB();
    B.addUser(tempObj);
}

И поэтому каким-то образом я не могу заставить указатель параметра использовать метод доступа (см. Строку, помеченную (1)). Может кто-нибудь дать мне быстрое решение? Я искал способ сделать это, но, похоже, ни у кого нет средств доступа с параметрами, указывающими на объект.

Ответы [ 4 ]

2 голосов
/ 03 февраля 2012

У вас есть ряд вопросов здесь. Позвольте мне обратиться к некоторым из них для вас.

Вы заявляете:

     unsigned int _uid; //user identifier

Но ваш добытчик для этого:

    int getUserID();

Это рискует усечением. Должно быть:

    unsigned int getUserID() const;

const потому что вы не изменяете экземпляр class.

Это будет определено:

unsigned int A::getUserID() const
{
    return _uid;
}

Далее этот метод фантома class:

void UserDB::adduser(A* newUser)

Вы сказали:

Я искал способ сделать это, но, похоже, ни у кого нет средств доступа с параметрами, указывающими на объект.

Это потому, что в таком class нет необходимости. Вы должны предпочесть пройти по ссылке здесь. const - ссылка была бы лучше, но давайте не будем слишком сильно менять ...

void UserDB::adduser(A& newUser)
{
    if (newUser.getUserID() == 0)
    {
        //Something is done if the condition is true;
    }
};

Там нет синтаксической ошибки! Для указателя сначала нужно проверить, что это не NULL, а затем использовать оператор ->, а не .. Ссылки намного чище.

Вперед, затем, к ...

int main(){

    A tempObj;

Это создает экземпляр A в стеке, вызывая конструктор по умолчанию. Вам это не нужно, просто удалите его.

    UserDB B;

Это создает B в стеке, снова вызывая конструктор по умолчанию. Я собираюсь оставить это в покое.

    //Assume the 7 following variables have been initialized correctly.

Хорошо. Только один раз.

    tempObj = new A(uloginName, password, userID, groupID, gecos, homeDirectory, shell);

Ты не можешь этого сделать! tempObj был A, а не A*. Вместо этого просто создайте A в стеке, вызывая второй конструктор:

    A tempObj(uloginName, password, userID, groupID, gecos, homeDirectory, shell);

Теперь на ...

    B = new UserDB();

Опять же, вы не можете этого сделать. B - это UserDB, а не UserDB*. Просто удалите эту строку, она не нужна, так как вы уже создали ее в стеке!

Эта строка почти правильная ...

    B.addUser(tempObj);

... но C ++ чувствителен к регистру! Использование:

    B.adduser(tempObj);

И ваш код должен скомпилироваться.

Время прочитать книгу или две !

1 голос
/ 02 февраля 2012

Измените if(newUser.getUserID == 0) на if(newUser->getUserID() == 0)
и B.addUser(tempObj); на B->addUser(&tempObj);

Вам также необходимо объявить tempObj и B объекты в качестве указателя:

UserDB* B
A* tempObj;

Конечно, не рекомендуется использовать указатели, если вам это не нужно из-за проблем с управлением памятью, с которыми вам приходится сталкиваться.Это способ обхода без указателей:

void UserDB::addUser(A newUser)
{
    if(newUser.getUserID() == 0)
    {
        //Something is done if the condition is true;
    } 
};

int main(){    
    //Assume the 7 following variables have been initialized correctly.
    char uloginName[9];
    char homeDirectory[33];
    int userID;
    int groupID;
    char password[17];
    char shell[17];
    char gecos[65];
    UserDB B;
    A tempObj(uloginName, password, userID, groupID, gecos, homeDirectory, shell);
    B.addUser(tempObj);
}

Для повышения производительности лучше передать newUser параметр по ссылке , чтобы он не копировался при передаче в addUser метод.И сделайте это const, чтобы убедиться, что его значение не было случайно изменено в методе addUser:

void UserDB::addUser(const A &newUser)
{
    if(newUser.getUserID() == 0)
    {
        //Something is done if the condition is true;
    } 
};
1 голос
/ 02 февраля 2012

Я предполагаю, что tempObj должен быть указателем здесь: A tempObj = new A();, поэтому он должен выглядеть следующим образом:

int main()
{
    // ...
    A* tempObj = new A(uloginName, password, userID, groupID, gecos, homeDirectory, shell);
    UserDB B;
    B.addUser(tempObj);
    // ...
    delete tempObj;
    return 0;
}

И if(newUser.getUserID == 0) предполагается равным if(newUser->getUserID() == 0), поскольку вы имеете дело с указателем, а getUserID является методом, а не переменной-членом.

Надеюсь, это поможет.

0 голосов
/ 02 февраля 2012

newUser - указатель, поэтому вам нужно либо (*newUser)., либо newUser->, чтобы получить доступ к тому, на что он указывает.

Для вызова функции необходимо использовать оператор вызова функции ().

Тогда вы получите

newUser->getUserID()
...