Thread: Error only on Visual Studio

  1. #1
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154

    Error only on Visual Studio

    Hello fellows.
    I have tested the above code to g++ and it's ok. It does compile.
    Code:
    class Player {
     private:
    	 string name;
     public:
    	 Player(const string &n)
    	 {
    		 name = n;
    	 }
    
    	 virtual ~Player() { }
    
    
    	virtual const string & getType() const = 0;
    
    	virtual Move play(const State &s) = 0;
    
    	friend ostream & operator << (ostream &out, const Player &player);
    
    };
    
    ostream & operator << (ostream &out, const Player &player)
    {
    	out << player.getType() << " player " << player.name;
    
    	return out;
    }
    I have tested on Visual Studio 2015 (C++14) and at the line out << player.getType() << " player " << player.name; i get the error error C2259: 'Player': cannot instantiate abstract class

    I can't fix that error because i can't understand it. What's wrong ?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Do you have a main function?

    Put it another way: do you have code that tests this class? If you don't, then we've just discovered a serious bug in the Visual Studio 2015 compiler. More likely you have say, a main function in which you did try to instantiate this class to test, and Visual Studio correctly reported the error. g++ may have not detected it because you only compiled the source file excluding the testing code (maybe, with only this fragment of code, I'm just guessing.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154
    Yes, i do have code to test this function.
    Yes, i do have main.
    No i don't instantiate object of Player. Instead, i do instantiate subclasses of Player (such as GreedyPlayer) which are not abstract (all pure virtual functions have been overriden).

    Just to add that in g++ it also runs fine. No errors, and the expected output comes "naturally".

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Could you post the smallest and simplest version of this program that compiles on g++ but fails to compile on the Visual Studio 2015 compiler with this error message?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154
    Check attachements.

    2 headers (one with the problematic code)
    1 cpp with main.

    This minimal edition compiles and run on g++ (linux).

    I've tried on two different machines with VS 2015 Express edition (C++14).

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I'm afraid that I cannot replicate this error with Visual Studio 2019 set to compile with respect to C++14: the compilation is successful. I don't have a copy of Visual Studio 2015.

    A few suggestions though:
    • I used to think that this was just being pedantic, until coming across a case where it really did matter: names that begin with an underscore followed by an uppercase character, or which contain consecutive underscores, are reserved to the implementation for any use. Hence, your header guard names _SP_PLAYER_ and _SP_MOVE_ are actually reserved and hence should not be used. Easy alternatives include SP_PLAYER_H_ and SP_MOVE_H_
    • Do not place using directives or using declarations at file scope in header files, or before header inclusions. That is, your using namespace std; in test.cpp should be moved to after the header inclusions, and your header files should be written such that there is no using namespace std; at file scope (but function scope is fine). This way, you avoid accidentally using unqualified names that you did not expect, or create name collisions when your header files are included elsewhere.
    • If you are going to initialise a member variable to a constant by default, do it at the declaration, e.g.,
      Code:
      std::string type{"Greedy"};
      Otherwise, make more extensive use of the constructor's initialiser list.
    • Your State class does not handle copying properly. You can avoid dealing with that yourself by turning the c member variable into a std::vector<int>, which would allow you to get rid of the destructor at the cost of modifying the constructor slightly. It would probably be better to just use the more descriptive name coins instead of c.
    • Although it is probably unnecessary since you're just testing, in practice instead of direct use of new and delete you might consider:
      Code:
      std::unique_ptr<Player> p = std::make_unique<GreedyPlayer>("Tom");
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by laserlight View Post
    I used to think that this was just being pedantic, until coming across a case where it really did matter: names that begin with an underscore followed by an uppercase character, or which contain consecutive underscores, are reserved to the implementation for any use. Hence, your header guard names _SP_PLAYER_ and _SP_MOVE_ are actually reserved and hence should not be used. Easy alternatives include SP_PLAYER_H_ and SP_MOVE_H_
    Same thing here... I used to name things with an underscore until I've got a conflict... Same thing to the suffix _t for typedefs. Now, the tags of structures, unions and enums I use _s, _u and _e, respectively... And for typedefs I use _T (uppercase t). Specially glibc documentation tells us _t is reserved...

  8. #8
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154
    Thanks for the advices lasrlight.
    This code is not for bussiness. I was just helping someone and, while i was so sure that it does compile, i was surprised.

    The above is the minimal which is not been compiled either.

    Code:
    #include <iostream>
    using namespace std;
    
    class Player {
    private:
    	string name;
    public:
    	Player(const string &n)
    	{
    		name = n;
    	}
    
    	virtual ~Player() { }
    
    
    	virtual const string & getType() const = 0;
    
    
    	friend ostream & operator << (ostream &out, const Player &player);
    
    
    };
    
    ostream & operator << (ostream &out, const Player &player)
    {
    	out << player.getType() << " player " << player.name;
    
    	return out;
    }
    
    /*+++++++++++++++++++++++++++++++++++++++++++++++++++*/
    class GreedyPlayer : public Player
    {
    private:
    	string type {"Greedy"};
    
    public:
    	GreedyPlayer(const string &n) : Player(n){}
    
    	~GreedyPlayer() {}
    
    	const string & getType() const	{ return type;}
    };
    
    
    int main() {
    
    	Player *p = new GreedyPlayer("Tom");
    
    	cout << *p;
    
    	delete p;
    
     return 0;
    }
    I suppose that the problem hides somewhere behind friend and/or operator.

  9. #9
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154
    I have just found the solution.

    The ostream couldn't find the way to print string. I've just included <string> and it does compile finally.

    I've removed const from player and then the error changed to "no ostream const string operator exists" or something similar. So i've tried to include string and ta da.

  10. #10
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154
    But i have to admit that the compilation errors have lead me to another direction.

  11. #11
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    154
    I used to think that this was just being pedantic, until coming across a case where it really did matter: names that begin with an underscore followed by an uppercase character, or which contain consecutive underscores, are reserved to the implementation for any use. Hence, your header guard names _SP_PLAYER_ and _SP_MOVE_ are actually reserved and hence should not be used. Easy alternatives include SP_PLAYER_H_ and SP_MOVE_H_
    It may be my confusion for years. I believed the exact opposite. That is, i have to use underscore in front of, so as to avoid collision with reserved definitions. Thanks for the correct reminding.

    "repetition is the mother of learning"

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Oh yes, it is good to see that you have found the issue. My mistake too: I should have asked if you really couldn't make the program smaller: at a glance for your program in post #8, I noticed that you didn't #include <string> because it was easy to see with everything in just a few lines.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. stripy Error in Visual Studio 2013
    By Daniel Cadwell in forum C++ Programming
    Replies: 4
    Last Post: 07-09-2015, 11:07 PM
  2. error configuring Qt for Visual studio
    By heisel in forum C++ Programming
    Replies: 10
    Last Post: 10-02-2009, 09:16 AM
  3. Compiling Error in Visual Studio 2005
    By JeroG in forum C++ Programming
    Replies: 4
    Last Post: 02-06-2009, 09:26 AM
  4. Visual Studio C++, syntax error : ']'
    By Sparrowhawk in forum C Programming
    Replies: 26
    Last Post: 10-15-2008, 03:14 AM
  5. Uninstall Visual Studio Error
    By MrWizard in forum Tech Board
    Replies: 10
    Last Post: 09-08-2002, 04:34 PM

Tags for this Thread