locked
LNK2019 ERROR from overloading<< input operator RRS feed

  • Pergunta

  • I'm going to make this short and sweet.

    I have two modules, MotorVehicle and Truck, Truck is derived from MotorVehicle.

    Here is MotorVehicle Module

    //MotorVehicle.h

    #ifndef SDDS_MOTORVEHICLE_H #define SDDS_MOTORVEHICLE_H #include <iostream> namespace sdds { class MotorVehicle { private: char m_plate[33]; char m_address[65]; int m_year; public: MotorVehicle(); MotorVehicle(const char* plate, int year); void moveTo(const char* address); std::ostream& write(std::ostream& os)const ; std::istream& read(std::istream& in); }; std::ostream& operator<<(std::ostream& os, const MotorVehicle& mv); std::istream& operator>>(std::istream& in, MotorVehicle& mv); } #endif

    //MotorVehicle.cpp

    #define _CRT_SECURE_NO_WARNINGS

    #include "MotorVehicle.h"

    namespace sdds {

    MotorVehicle::MotorVehicle() {
    m_plate[0] = '\0';
    m_address[0] = '\0';
    m_year = 0;
    }

    MotorVehicle::MotorVehicle(const char* plate, int year) {
    //Transfer license plate info
    strncpy(m_plate, plate, 32);

    //Transfer Year
    m_year = year;

    //Set default address
    strcpy(m_address, "Factory");
    }

    void MotorVehicle::moveTo(const char* address) {
    //Compare addresses
    if (strcmp(m_address, address)) {
    //Format output, align to right and then left, change widths for each field
    std::cout.setf(std::ios::right);

    std::cout.width(10);
    std::cout << "|" << m_plate << "|";
    std::cout << " ";
    std::cout.width(20);
    std::cout << "|" << m_address;
    std::cout << " --->--- ";
    std::cout.setf(std::ios::left);
    std::cout.width(20);
    std::cout << address << "|" << std::endl;

    //Transfer Address
    strncpy(m_address, address, 64);
    }
    }

    std::ostream& MotorVehicle::write(std::ostream& os)const {
    //Output MotorVehicle Atrriubutes
    os << "| " << m_year << " | " << m_plate << " | " << m_address;

    //Return os to client
    return os;
    }

    std::istream& MotorVehicle::read(std::istream& in) {
    //Grab data from user, transfer into attributes
    std::cout << "Built year: ";
    in >> m_year;
    std::cout << std::endl << "License plate: ";
    in >> m_plate;
    std::cout << std::endl << "Current location: ";
    in >> m_address;

    return in;
    }

    std::ostream& operator<<(std::ostream& os, MotorVehicle& mv) {
    //Call write function with ostream obj
    mv.write(os);

    //return ostream obj
    return os;
    }

    std::istream& operator>>(std::istream& in, MotorVehicle& mv) {
    //call read function istream obj
    mv.read(in);

    //return istream obj
    return in;
    }

    }

    Here is my Truck Module

    //Truck.h

    #ifndef SDDS_TRUCK_H #define SDDS_TRUCK_H #include "MotorVehicle.h" namespace sdds{ class Truck : public MotorVehicle{ private: double m_capacity; double m_cargo; public: Truck(const char* plate, int year, double capacity, const char* address); bool addCargo(double cargo); bool unloadCargo(); std::ostream& write(std::ostream& os) const; std::istream& read(std::istream& in); }; std::ostream& operator<<(std::ostream& os, const Truck& t); std::istream& operator>>(std::istream& in, Truck& t); } #endif

    //Truck.cpp

    #define _CRT_SECURE_NO_WARNINGS

    #include "Truck.h"

    namespace sdds {

    Truck::Truck(const char* plate, int year, double capacity, const char* address) : MotorVehicle(plate, year){
    //Set base class attributes through default constructor

    //Set cargo attributes
    m_capacity = capacity;
    m_cargo = 0;

    //Set address via moveTo function
    MotorVehicle::moveTo(address);
    }

    bool Truck::addCargo(double cargo) {
    //Check if cargo can be added
    if (m_cargo + cargo < m_capacity) {
    //add and update cargo
    m_cargo += cargo;
    }

    //Return logic
    return (m_cargo + cargo < m_capacity);
    }

    bool Truck::unloadCargo() {
    //Find if cargo will be changed
    bool rtn = !(m_cargo == 0);

    //Unload cargo
    m_cargo = 0;

    return rtn;
    }

    std::ostream& Truck::write(std::ostream& os)const {
    //Call base class write;
    MotorVehicle::write(os);

    //Output truck attributes
    os << " | " << m_cargo << "/" << m_capacity;

    return os;
    }

    std::istream& Truck::read(std::istream& in) {
    //Grab data from user, transfer into attributes
    MotorVehicle::read(in);
    std::cout << std::endl << "Capacity: ";
    in >> m_capacity;
    std::cout << std::endl << "Cargo: ";
    in >> m_cargo;

    return in;
    }

    std::ostream& operator<<(std::ostream& os, Truck& t) {
    //Call write function with ostream obj
    t.write(os);

    //Return ostream obj
    return os;
    }

    std::istream& operator>>(std::istream& in, Truck& t) {
    //Call read function with istream obj
    t.read(in);

    //Return istream obj
    return in;
    }

    }

    And my client code

    #include<iostream>
    #include "Truck.h"
    #include "Truck.h" // intentional
    #include "MotorVehicle.h"
    #include "MotorVehicle.h" // intentional
    
    using namespace std;
    using namespace sdds;
    
    void printHeader(const char* title)
    {
    	char oldFill = cout.fill('-');
    	cout.width(40);
    	cout << "" << endl;
    
    	cout << "|> " << title << endl;
    
    	cout.fill('-');
    	cout.width(40);
    	cout << "" << endl;
    	cout.fill(oldFill);
    }
    
    void moveAndLoad(Truck& aTruck, const char* destination, double cargo)
    {
    	//cout << aTruck << endl;
    	aTruck.moveTo(destination);
    	if (aTruck.addCargo(cargo))
    		cout << "Cargo loaded!\n";
    	else
    		cout << "Adding cargo failed!\n";
    	cout << aTruck << endl << endl;
    }
    
    void moveAndUnload(Truck& aTruck, const char* destination)
    {
    	//cout << aTruck << endl;
    	aTruck.moveTo(destination);
    	if (aTruck.unloadCargo())
    		cout << "Cargo unloaded!\n";
    	else
    		cout << "Unloading cargo failed!\n";
    	cout << aTruck << endl << endl;
    }
    
    int main()
    {
    	{
    		printHeader("T1: Vehicle");
    
    		MotorVehicle aVehicle("VVV-111", 2010);
    		cout << aVehicle << endl << endl;
    
    		aVehicle.moveTo("Downtown Toronto");
    		aVehicle.moveTo("Mississauga");
    		aVehicle.moveTo("North York");
    
    		cout << endl << aVehicle << endl << endl;
    
    		printHeader("T2: Read/Write");
    		cin >> aVehicle;
    		cout << endl << aVehicle << endl << endl;
    	}
    
    	{
    		printHeader("T3: Truck");
    
    		Truck aTruck("T-1111", 2015, 5432, "Toronto HQ");
    		cout << endl;
    
    		moveAndLoad(aTruck, "Toronto Deposit", 2345);
    
    		moveAndLoad(aTruck, "Montreal", 3456);
    
    		moveAndLoad(aTruck, "New York", 4567);
    
    		moveAndUnload(aTruck, "New Jersey");
    
    		moveAndUnload(aTruck, "Toronto");
    
    
    		printHeader("T4: Read/Write");
    		cin >> aTruck;
    		cout << endl << (MotorVehicle)aTruck;
    		cout << endl << aTruck << endl << endl;
    	}
    }

    And the errors...

    1>main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl sdds::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class sdds::MotorVehicle const &)" (??6sdds@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@ABVMotorVehicle@0@@Z) referenced in function _main
    
    1>main.obj : error LNK2019: unresolved external symbol "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl sdds::operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class sdds::Truck const &)" (??6sdds@@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV12@ABVTruck@0@@Z) referenced in function "void __cdecl moveAndLoad(class sdds::Truck &,char const *,double)" (?moveAndLoad@@YAXAAVTruck@sdds@@PBDN@Z)

    This started once i replaced the input operator function from this

    std::ostream& operator<<(std::ostream& os, MotorVehicle& mv);

    std::ostream& operator<<(std::ostream& os, Truck& t);

    to this

    std::ostream& operator<<(std::ostream& os, constMotorVehicle& mv);
    std::ostream& operator<<(std::ostream& os,const Truck& t);

    i also added made both write() functions for each class a constant if that's any info.

    Any help is appreciated, really hate lnk errors and can never solve them




    • Editado Noah Pereira quinta-feira, 16 de julho de 2020 01:59
    quinta-feira, 16 de julho de 2020 01:41

Respostas

  • Hi,

    Thank you for posting here.

    >>LNK2019 ERROR from overloading<< input operator

    I noticed that in your class definition you have:

    class MotorVehicle {
        private:
            char m_plate[33];
            char m_address[65];
            int m_year;
    
        public:
            MotorVehicle();
            MotorVehicle(const char* plate, int year);
    
            void moveTo(const char* address);
    
            std::ostream& write(std::ostream& os)const;
            std::istream& read(std::istream& in);
        };
    
        std::ostream& operator<<(std::ostream& os, const MotorVehicle& mv);
        std::istream& operator>>(std::istream& in, MotorVehicle& mv);
    
    }

    There is "const" before MotorVehicle& mv.

    However later in your code you have:

    std::ostream& operator<<(std::ostream& os,  MotorVehicle& mv)

    There is no "const" before MotorVehicle& mv.

    As far as I'm concerned you should make them same( both have "const").

    For "Truck", the same, you should also make them same( both have "const").

    Best Regards,

    Jeanine Zhang


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marcado como Resposta Noah Pereira quinta-feira, 16 de julho de 2020 03:29
    quinta-feira, 16 de julho de 2020 03:17

Todas as Respostas

  • The posted code has declarations for the functions noted in the LNK2019 error messages.

    But where are the definitions of those functions?

    The linker is telling you that the code is referencing functions that it cannot find (i.e., don't exist in your module).

    quinta-feira, 16 de julho de 2020 01:53
  • The posted code has declarations for the functions noted in the LNK2019 error messages.

    But where are the definitions of those functions?

    The linker is telling you that the code is referencing functions that it cannot find (i.e., don't exist in your module).

    sorry i updated it now, didn't wanna crowd the question
    quinta-feira, 16 de julho de 2020 02:27
  • Hi,

    Thank you for posting here.

    >>LNK2019 ERROR from overloading<< input operator

    I noticed that in your class definition you have:

    class MotorVehicle {
        private:
            char m_plate[33];
            char m_address[65];
            int m_year;
    
        public:
            MotorVehicle();
            MotorVehicle(const char* plate, int year);
    
            void moveTo(const char* address);
    
            std::ostream& write(std::ostream& os)const;
            std::istream& read(std::istream& in);
        };
    
        std::ostream& operator<<(std::ostream& os, const MotorVehicle& mv);
        std::istream& operator>>(std::istream& in, MotorVehicle& mv);
    
    }

    There is "const" before MotorVehicle& mv.

    However later in your code you have:

    std::ostream& operator<<(std::ostream& os,  MotorVehicle& mv)

    There is no "const" before MotorVehicle& mv.

    As far as I'm concerned you should make them same( both have "const").

    For "Truck", the same, you should also make them same( both have "const").

    Best Regards,

    Jeanine Zhang


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marcado como Resposta Noah Pereira quinta-feira, 16 de julho de 2020 03:29
    quinta-feira, 16 de julho de 2020 03:17
  • Hi,

    Thank you for posting here.

    >>LNK2019 ERROR from overloading<< input operator

    I noticed that in your class definition you have:

    class MotorVehicle {
        private:
            char m_plate[33];
            char m_address[65];
            int m_year;
    
        public:
            MotorVehicle();
            MotorVehicle(const char* plate, int year);
    
            void moveTo(const char* address);
    
            std::ostream& write(std::ostream& os)const;
            std::istream& read(std::istream& in);
        };
    
        std::ostream& operator<<(std::ostream& os, const MotorVehicle& mv);
        std::istream& operator>>(std::istream& in, MotorVehicle& mv);
    
    }

    There is "const" before MotorVehicle& mv.

    However later in your code you have:

    std::ostream& operator<<(std::ostream& os,  MotorVehicle& mv)

    There is no "const" before MotorVehicle& mv.

    As far as I'm concerned you should make them same( both have "const").

    For "Truck", the same, you should also make them same( both have "const").

    Best Regards,

    Jeanine Zhang


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thank you, such a simple mistake
    quinta-feira, 16 de julho de 2020 03:29