Passing arguments to function



  • Hi,
    i have here a silly question, so if this question has already been covered somewhere, please point me there, i didnt find it.
    I have a class, which contains a function for reading files. It takes a QDir as argument. I tried it like this

    class MyFileIO
    {
        public:
            QString readFile( QDir  &Path);
    };
    

    and calling it like this

    void MainWindow::on_btnInput_clicked()
    {
        QDir *dir = new QDir(QString());
        MyFileIO::readFile(dir );
    }
    

    It says no matching function for call to 'MyFileIO::readDorfFile(QDir*&)'
    and
    no known conversion for argument 1 from 'QDir*' to 'QDir&'
    I tried it with passing it by value, by const &, non worked.


  • Moderators

    Ok, so almost every line of this code is wrong in some way ;) Lets go over them one by one.

    QString readFile( QDir  &Path);
    

    Path is an "in" parameter, i.e. it is meant to pass data into the function, not out of it. Therefore you should use a const reference.
    It's also a little weird to pass a path as QDir. QString would be a more common choice for it:

    QString readFile(const QString& path);
    

    On to the other function:

    QDir dir = new QDir(QString());
    

    This makes no sense whatsoever. new allocates memory and returns a pointer. You then assign a pointer to a QDir variable...
    Also the parameter to QDir constructor is defaulted to QString(), so this line should simply be:

    QDir dir;
    

    Next:

    MyFileIO::readFile(dir );
    

    You call readFile as if it were a static method of MyFileIO class, but it's not. Either make it static:

    public:
       static QString readFile(const QDir& path);
    

    or you need an instance of the class to call it on:

    MyFileIo fileIO;
    fileIO.readFile(dir);
    

    It seems a static method for this would make more sense, but then again why do you even need a class for it? You could just make it a free standing function (namespaced if you'd like).



  • Ofcourse i ment QDir *dir = new QDir(QString());

    "static QString readFile(const QString& path);" and "QDir dir;" seem to work, thank you.
    Whats the reason it have to be const&? And why i cant pass the pointer of QDir to the function?

    I made it a class, course i thought it would be nicer to encapsulate it somehow


  • Moderators

    It should be const because it is not going to be changed inside the method (make it const to not to change it by accident inside the function/method). Declaring it const you achieve two things:

    1. It cannot be changed by accident
    2. The reader of your code knows that the data passed to this method will not be changed

    If you want to pass a pointer to a function/method then you have to declare the parameter as pointer, not reference:

    void readFile(const QString* path);
    

    Here const again to not to change the data path is pointing to.


  • Moderators

    Well it doesn't have to be const, it's just what @jsulm said. It prevents simple bugs and expresses intent (self-documents).
    If it wasn't const the user of your class would think that the function "returns" something in that parameter, but it would be weird to return a path in a readFile method. Usually there would be a getter function for this like QString path() const; in your class.

    You can pass a pointer but the question is "why?". It's again a question of good api design. Passing via pointer indicates to the user that it's an optional parameter (i.e. you can pass nullptr). A const reference can't be null so it expresses that the parameter is required. One extra benefit of the const there is that now you can pass a temporary object or a default parameter like this:

    static QString readFile(const QString& path = QString());
    

    so you can call it without parameters too. Without the const you would be passing a reference to a temporary object and the compiler would complain. Note that this doesn't make the path optional. It's still required but you provide it yourself if the uses doesn't.

    Using QDir for file path parameter is a bad idea because it limits your api unnecessarily. Not all kinds of paths can be stored as QDir, but most of them can as a QString.

    A general concept of a class is that it encapsulates some state and provides access methods to it. If your function does not modify any non-static state of the class it might as well be a free function.



  • Thanks, am aware of almost all of it, except passing the pointer of a heap object as argument. Why cant i do it?


  • Moderators

    @Maser said:

    passing the pointer of a heap object as argument. Why cant i do it?

    I never said you can't do something like that, have I? I just said that passing a pointer indicates to the user that it's optional.
    If you wanted an optional parameter of type QDir you could do:

    static QString readFile(const QDir* path = nullptr);
    

    and then pass a stack variable address:

    QDir dir;
    MyFileIO::readFile(&dir);
    

    or a heap one (but this is really weird and unnecessary, don't do that):

    QDir* dir = new QDir();
    MyFileIO::readFile(dir);
    delete dir;
    


  • Your right, though it stil has to be static and const. But this obv has more to do with c++ than Qt, so id have to do some reading on that subject.
    Thank you both.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.