LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-20-2020, 03:55 PM   #1
maschelsea
Member
 
Registered: Dec 2016
Distribution: Slackware 64bit 14.2
Posts: 468

Rep: Reputation: Disabled
Horse and Pegasus 1


I named my thread that because I have a feeling that this chapter will be problematic for me. I am working out of Sams Teach Yourself C++ For Linux in 21 Days. I'm on Day 13. I have typed in the listing for 13.2. When I tried to compile it, it erred greatly. I'm thinking that I have failed to observe one of C++'s unwritten rules that cause compilers to fail with no hint as to what the actual problem is. For starters, here's my error list:
Code:
michael@caitlyn 13 $ g++ listing13.2.cpp -o listing13.2
listing13.2.cpp: In function 'int main()':
listing13.2.cpp:24:11: error: 'Ranch' was not declared in this scope
    Horse* Ranch[NumberHorses];
           ^
listing13.2.cpp:25:11: error: 'pHorse' was not declared in this scope
    Horse* pHorse;
           ^
listing13.2.cpp:32:16: error: 'Pegasus' does not name a type
   pHorse = new Pegasus;
                ^
listing13.2.cpp:34:16: error: 'Horse' does not name a type
   pHorse = new Horse;
                ^
listing13.2.cpp:40:16: error: 'pPeg' was not declared in this scope
       Pegasus *pPeg = dynamic_cast <Pegasus*> (Ranch[i]);
                ^
listing13.2.cpp:40:37: error: 'Pegasus' does not name a type
       Pegasus *pPeg = dynamic_cast <Pegasus*> (Ranch[i]);
                                     ^
listing13.2.cpp:40:44: error: expected '>' before '*' token
       Pegasus *pPeg = dynamic_cast <Pegasus*> (Ranch[i]);
                                            ^
listing13.2.cpp:40:44: error: expected '(' before '*' token
listing13.2.cpp:40:45: error: expected primary-expression before '>' token
       Pegasus *pPeg = dynamic_cast <Pegasus*> (Ranch[i]);
                                             ^
listing13.2.cpp:40:57: error: expected ')' before ';' token
       Pegasus *pPeg = dynamic_cast <Pegasus*> (Ranch[i]);
                                                         ^
Here is the code listing:
Code:
michael@caitlyn 13 $ cat listing13.2.cpp
//Listing 13.2 - Using dynamic_cast
//2020-10-20
#include <iostream>
enum TYPE { Horse, Pegasus };

class Horse
{
   public:
      virtual void Gallop() { std::cout << "Galloping...\n"; }
   private:
      int itsAge;
};

class Pegasus : public Horse
{
   public:
      virtual void Fly() { std::cout << "I can fly!  I can fly!  I can fly!\n"; }
};

const int NumberHorses = 5;

int main()
{
   Horse* Ranch[NumberHorses];
   Horse* pHorse;
   int choice, i;
   for(i = 0;i<NumberHorses;i++)
   {
      std::cout << "(1)Horse, (2)Pegasus:  ";
      std::cin >> choice;
      if (choice == 2)
	 pHorse = new Pegasus;
      else
	 pHorse = new Horse;
      Ranch[i] = pHorse;
   }
   std::cout << "\n";
   for (i = 0; i < NumberHorses; i++)
   {
      Pegasus *pPeg = dynamic_cast <Pegasus*> (Ranch[i]);
      if (pPeg)
	 pPeg->Fly();
      else
	 std::cout << "Just a horse.\n";
      delete Ranch[i]
   }
   return 0;
}
I find myself wondering why they included that enum just after the #include. They never reference TYPE.

Last edited by maschelsea; 10-20-2020 at 03:56 PM.
 
Old 10-20-2020, 04:45 PM   #2
boughtonp
Senior Member
 
Registered: Feb 2007
Location: UK
Distribution: Debian
Posts: 3,597

Rep: Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545Reputation: 2545

I don't know C++ but assuming Ranch is supposed to be an array of pointers, I thought that was written as "Horse *Ranch[NumberHorses]" ?

Do you have a copy that includes a CD and/or download link for the code examples, thus avoiding the need to type them out?

 
Old 10-20-2020, 04:47 PM   #3
maschelsea
Member
 
Registered: Dec 2016
Distribution: Slackware 64bit 14.2
Posts: 468

Original Poster
Rep: Reputation: Disabled
It shouldn't matter where the * occurs. My book claims that C++ ignores white space. So Horse* Ranch = Horse *Ranch.

Thank you, however, for trying to help.

Last edited by maschelsea; 10-20-2020 at 04:48 PM.
 
Old 10-20-2020, 05:11 PM   #4
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
The enum at the top makes no sense and is pollution the namespace. Remove it and add the missing semicolon after "delete Ranch[i]" and it should compile. Are you sure copied that correctly?
 
Old 10-20-2020, 05:16 PM   #5
maschelsea
Member
 
Registered: Dec 2016
Distribution: Slackware 64bit 14.2
Posts: 468

Original Poster
Rep: Reputation: Disabled
I removed the enum TYPE at the top of the program and added the semicolon after delete Ranch[i] and it compiled perfectly. Thank you for your help. I am still confused by the multitude of errors that it gave me. Why would it complain about my enum line without complaining about my enum line?
 
Old 10-20-2020, 07:30 PM   #6
SoftSprocket
Member
 
Registered: Nov 2014
Posts: 399

Rep: Reputation: Disabled
In and of itself the enum is fine. The problem is that it makes it impossible for the compiler to discern the meaning of "Horse* Ranch[NumberHorses];" An enumeration is probably only a right hand value and suitable for assignment or comparison (I say probably since to be sure I would have to look in the C++ specification) whereas the statement requires a type on the left side to make sense.

The compiler might have said, "this statement makes no sense to me", but they don't tend to say such things so when you see a statement such as "'Ranch' was not declared in this scope" when the statement was meant to declare Ranch in this scope, you probably need to look for something that would cause confusion in the poor addled compilers mind.

Its often the case when debugging a program - or getting one to compile - you find yourself looking to a place other then where the error occurred because the error doesn't seem to make sense.
 
2 members found this post helpful.
Old 10-22-2020, 03:23 PM   #7
GazL
LQ Veteran
 
Registered: May 2008
Posts: 6,896

Rep: Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018Reputation: 5018
In the edition of the book I have (5th) this is actually Listing 14.2 and the enum is specified as "enum TYPE { HORSE, PEGASUS };" (upper-case, which is a common convention for enums: in C, if not in C++) so there's no name collision with the class.

Having said that, it's still an unused type so I'm not sure why they put it in there. The text following the previous listing talks about using an enumerated type to identify a class if your compiler doesn't support RTTI/dynamic_cast, and maybe that enum is eluding to that in some way, but they don't provide an example of that(that I saw, anyway).

I'm assuming something like this:
Code:
// equines.hh

#ifndef EQUINES_HH
#define EQUINES_HH

namespace Equines
{
    enum class Type { Unknown = 0, Donkey, Horse, Zebra, Pegasus };
    const char* TypeNames[] =
    {
        "Unknown", "Donkey", "Horse", "Zebra", "Pegasus"
    };
    
    class Equine
    {
      public:

        Type getType() const { return type; }
        
        const char* cTypeName() const { return TypeNames[ static_cast<int>(type) ] ;}
                  
        virtual ~Equine() { std::cout << cTypeName() << ", going to the Glue Factory!" << std::endl; }
      protected:
        Equine(Type type) : type(type) {}

      private:
        const Type type;
    };
    
    class Donkey : public Equine
    {
      public:
        Donkey() : Equine(Type::Donkey) {}
    };
    
    class Horse : public Equine
    {
      public:
        Horse() : Equine(Type::Horse) {}
    };
    
    class Zebra : public Equine
    {
      public:
        Zebra() : Equine(Type::Zebra) {}
    };
    
    class Pegasus : public Equine
    {
      public:
        Pegasus() : Equine(Type::Pegasus) {}
        bool fly() const { std::cout << "  I'm Flying!" << std::endl; return true; }
        ~Pegasus() { std::cout << "Pegasus Landing" << std::endl; }
    };
}

#endif
Code:
// horses.cc

#include <iostream>

#include "equines.hh"

int main()
{
    constexpr size_t max_horses = 20;
    Equines::Equine* my_horses[max_horses];
    
    size_t i = 0;
    my_horses[i++] = new Equines::Horse;
    my_horses[i++] = new Equines::Horse;
    my_horses[i++] = new Equines::Pegasus;
    my_horses[i++] = new Equines::Zebra;
    my_horses[i++] = new Equines::Pegasus;


    for( size_t j = 0 ; j < i ; j++ )
    {
        std::cout << my_horses[j]->cTypeName() << std::endl;
        if ( my_horses[j]->getType() == Equines::Type::Pegasus )
        {
            Equines::Pegasus *p = static_cast<Equines::Pegasus*> (my_horses[j]);
            p->fly();
        }
    }

    for ( size_t j = 0 ; j < i ; j++ )
    {
        delete my_horses[j];
        my_horses[j] = nullptr;
    }
    
    std::cout << "Done." << std::endl;
    
    return 0;
}
I'm not really a C++ guy, so the above may be a horrible idea, but I'm sure someone will pop in and say so if it is.

Last edited by GazL; 10-22-2020 at 03:42 PM. Reason: Made ~equine() virtual.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LFS and Pegasus usb module bigge Linux - Networking 0 11-18-2005 07:56 AM
Pegasus USB module RickRalph Debian 1 03-30-2005 08:00 PM
Pegasus: Unknown symbols on 2.6.6 kernel lrt2003 Linux - Hardware 4 06-14-2004 08:47 AM
2.4.22 -> 2.6.6 (usbcore issues - pegasus - eth1 - internet connection) lrt2003 Slackware 1 06-13-2004 02:19 AM
Pegasus USB dhcp-boot driver atlesn Linux - Networking 0 11-24-2003 03:01 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:18 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration