Nicholas Corin
Nicholas Corin

Reputation: 2404

warning: control reaches end of non-void function - Qt Application

I'm having an issue with polymorphism at the moment it seems. I have a base class called Asset, then 3 classes that inherit from that class - Bond, Saving and Stock. There is a function inside the Asset class called value() which is not implemented in this class, but rather in each of the derived classes. I came across some errors and was told that I should make the function virtual which stopped the compiler telling me I never implemented the function. But now I'm getting the error Warning: control reaches end of non-void function and my code won't run. I just added a cout << "Testing"; at the beginning of my code and still nothing. Here is my Asset class and then one of the implemented functions.

Asset.h

#ifndef ASSET_H
#define ASSET_H

#include <QString>
#include <QDate>

class Asset
{
public:
    Asset(QString, QDate);
    virtual double value() {};
    QString getDescription();
    QString getType();
protected:
    QString type;
    QDate date;
private:
    QString description;
};

#endif

Stock.cpp value function

double Stock::value()
{
    return sharePrice*numShares;    
}

I understand it's tough trying to piece together my code snippets. It doesn't seem decent to post all the files, there are a few. But I've linked the whole project onto Google Drive if you'd like to view it. https://drive.google.com/file/d/0B4hZjZFvvaTiWWlhXzF0YWQtcmc/edit?usp=sharing

Upvotes: 2

Views: 1166

Answers (3)

Your code, fixed, with commentary.

class Currency {
  // Never use a floating point type for currency.
  // Wrap, for example, Intel's DFP
  // http://www.netlib.org/misc/intel/
  ...
};

class Asset
{
    // Since you didn't implement the copy constructor,
    // and assignment operator, you must
    // disable the copying. Otherwise, you must implement them all,
    // and ideally the move constructor as well.
    Q_DISABLE_COPY(Asset)
public:
    // In Qt, it's idiomatic to pass the complex types via const
    // reference, although it's not end of the world not to do so.
    // Both are OK, since those "complex" types are cheap to copy.
    Asset(const QString &, const QDate &);
                    /** or **/
    Asset(QString, QDate);
    // A virtual destructor is necessary for a class that
    // can be derived from. Otherwise, inevitable type slicing will
    // lead to bugs. Remember: anyone is free to destruct the
    // derived class through a pointer to the base class!
    virtual ~Asset();
    // This is an abstract method, declare it as such.
    // It should also be const, since it's a getter.
    virtual Currency value() const = 0;
    // Getters should be const. The get prefix is redundant.
    QString description() const; 
    QString type() const;
protected:
    // Member data should have an agreed-upon prefix,
    // to prevent bugs when a local variable is referenced
    // instead of a member, and vice-versa.
    QString m_type;
    QDate m_date;
private:
    QString m_description;
};

class Stock : public Asset
{
   ...
public:
   // Q_DECL_OVERRIDE will trigger a compiler error
   // if we're not overriding a virtual method.
   Currency value() const Q_DECL_OVERRIDE;
   ...
};

Upvotes: 0

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

You have an unintended implementation (definition) for your function. In your class declaration change

class Asset {
    // ...
    virtual double value() {};
                        // ^^   <<<<<<<<<<< You don't want this
    // ...
};

to

class Asset {
    // ...
    virtual double value() = 0;
    // ...
};

In class Stock override the function

class Stock : public Asset {
    // ...
    virtual double value();
    // ...
};

The rest of the implementation is fine as it was before.

Upvotes: 3

Joel Rondeau
Joel Rondeau

Reputation: 7586

In looking at the code you have posted, I see an issue with Asset::value(), in that it doesn't return anything, and is likely the cause for the error that you show. Your two options are to make it pure virtual

virtual double value() = 0;

or to return a default value (likely 0)

virtual double value() {return 0.0;}

If this does not fix your issue, you should post more code.

Upvotes: 1

Related Questions