object& in turbo c++

Pages: 12
I'm working in Turbo c++ (I know it is outdated but we are required to work with it, so I have no other option.)

I came across this function declaration and could not figure out what the "Object&" is expecting.I'm trying to use the builtin doublelist implementation but I haven't been able to find any help on it.

Here is one of the functions defined by the compiler

1
2
3
4
5
6
7
8
9
10
11
void DoubleList::addAtHead( Object& toAdd )
{
    ListElement *newElement =
        new ListElement( &toAdd, head, head->next );
    CHECK( newElement != 0 );

    head->next->prev = newElement;
    head->next = newElement;

    itemsInContainer++;
}
Read up on references.
Hope this helps.
I do know what referencing means and what it does. What I don't understand is the "object" part.

I have tried working with the only example program that I could find. It uses a queue. It used the following call
1
2
3
Queue l;
...
l.add(*(new Time(Sample)));


Time is a class from the LTIME.H header and Sample is an object of Time declared just before.
However, when I try to replace Time with a simple class that I declared, I gives the error,
"temporary used in call for parameter o "

I haven't been able to make head or tail of this since I tried passing an object of a class as well as using the syntax used above in the code.


Ah, I see.

It looks like your Time class is a decendant of the Object class (as all the objects you add into the list must be).

It is using a horrible trick. Polymorphism works through pointers. So normally you write methods that take pointers. It would be something like:
void DoubleList::addAtHead( Object* toAdd );
But the code you've got wants an actual reference to an Object, not a pointer (yes, language semantics... but there are some guarantees in references not in pointers).

So when you add to the queue with
l.add( *(new Time(Sample)) );
what the compiler says is, "hey, that's supposed to be an Object -- apply polymorphism and it is -- sweet":
l.add( *( (Object*)(new Time(Sample)) ) );
Finally, the new object is dereferenced to get something that can be made into a reference.

Here's the rub. What happens to that Time object that was dynamically allocated on the heap? Is it lost, or would it just be simpler to say:
1
2
3
4
5
6
7
8
9
10
11
void DoubleList::addAtHead( Object* toAdd )
{
    ListElement* newElement =
        new ListElement( toAdd, head, head->next );
    CHECK( newElement != 0 );

    head->next->prev = newElement;
    head->next       = newElement;

    itemsInContainer++;
}

Hope this helps.
Thanks Duoas for that extremely quick response!

But I'm still a student and our teachers dont go much beyond our curriculum so I've had to learn some stuff by myself. In short I haven't got much idea about what you just said(sorry about that).

I know what polymorphism is and I've gone through all the header files related to this stuff but haven't been able to figure out what I'm supposed to pass to make it work ( and sadly ,still doesn't).
So, could you explain in a little more simpler terms about what I could do to apply this stuff to a make a queue of objects of my own class?

(yes, language semantics... but there are some guarantees in references not in pointers).


And could you explain what that means.]

Sorry to bother you and big thanks !!
After experimenting a bit , I did this
1
2
3
4
5
6
7
8
9
10
11
12
Queue Q;

class abc
{
 public: 
  int a;
  abc(int a1)
 { a1=a; 
 }
};

Q.put( *( (Object*)(new abc(5) ) ) )


That compiled fine. But now, when I use Q.get() , I get a (return-by-reference) object. How do I convert this back to my class abc type?

I have tried in vain to find some resources regarding these Object and Queue (with reference to Turbo c++) but couldn't find any. If someone knows, please let me know

You can't just make an 'abc' into an Object.

Somewhere in the library there must be a class called Object like this:

1
2
3
4
class Object
{
    //... details
};


If you want to make a class of objects that can be used everywhere an object of class Object can be used then you need to make your class a *subclass* of class Object:

1
2
3
4
class abc : public Object // now abs /is a/ Object
{
    //...
};


Then you can stuff objects of class abc everywhere you can stuff objects of class Object:

1
2
3
4
5
Queue Q;

abc a;

Q.put(a);

Last edited on
Yes, it was my mistake to use a direct C-style cast for you. Use a C++ cast instead:
*(dynamic_cast <Object*> ( new Foo ))
Then the compiler will properly complain when Foo is not a descendant of Object.
Read more here: http://www.cplusplus.com/doc/tutorial/typecasting/

Given
1
2
3
4
5
Queue Q;

abc a;

Q.put(a);
This will fail when a goes out of scope. (This is why I have a problem with the way the addAtHead()/put() function(s) are designed.)

Use a prototype like this:
void Queue::addAtHead( Object* toAdd );

Add stuff like this:
1
2
3
4
Queue q;
Abc* a = new Abc( "whatever" );
q.addAtHead( a );  // notice how a is a pointer
...

Good luck!
To Galik,
As I understand, if I make my class abc a subclass of Object, wouldn't that mean I will have to redefine all virtual functions defined in Object?

Correct me if I'm wrong.

To Duoas, I think you have given me the VS syntax,Turbo c++ does not all dynamic_cast etc.


Thanks
You only have to redefine (override) the PURE virtual functions if there are any. Otherwise you are not forced to override virtual functions that already have a definition in the base class.

You can't really avoid sub-classing class Object. The container class Queue may well be expecting to be able to call functions that class Object with provide.

The strong type system in C++ works to ensure that you only put classes of type Object (or subtypes thereof) into a container that expects them. It is rarely wise to bypass C++ type system using casts. And stuffing unexpected types into a container like class Queue, that is assuming the object you pass it will be of class Object, is asking for problems.
Did this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class abc :public Queue
{public: int a;
   abc(int a1)
  {a=a1;
  }
};

abc q;
for (int i=0;i<5;i++)
  q.add(i);

for (i=0;i<5;i++)
 cout<<q.get(i); 
   


this code gives me wierd result , it prints " Queue {} " 5 times. I did this because I didn't know else to. The Queue class is a subclass of Object class, so the arguments are accepted but I and unable to understand how to deal with the returned 'Object'. After I use the get() it returns a reference to Object but I'm unable to access the int variable that (I think) has been assigned 1-5.

Could somebody explain how to deal with the Objects or point me to some resource where I could read upon the matter( I haven't been able to find any yet!)

Thank you
We would need to see all the code for class Queue and class Object.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*------------------------------------------------------------------------*/
/*                                                                        */
/*  OBJECT.H                                                              */
/*                                                                        */
/*  Copyright Borland International 1991                                  */
/*  All Rights Reserved                                                   */
/*                                                                        */
/*------------------------------------------------------------------------*/

#if !defined( __OBJECT_H )
#define __OBJECT_H

#if !defined( __CLSTYPES_H )
#include <ClsTypes.h>
#endif  // __CLSTYPES_H

#if !defined( __CLSDEFS_H )
#include <ClsDefs.h>
#endif  // __CLSDEFS_H

#if !defined( __STDDEF_H )
#include <StdDef.h>
#endif  // __STDDEF_H

#if !defined( __IOSTREAM_H )
#include <iostream.h>
#endif  // __IOSTREAM_H

_CLASSDEF(Object)
_CLASSDEF(Error)

class _CLASSTYPE Object
{

public:

    virtual ~Object()
        {
        }

    virtual classType isA() const = 0;
    virtual char _FAR *nameOf() const = 0;
    virtual hashValueType hashValue() const = 0;
    virtual int isEqual( const Object _FAR & ) const = 0;

    virtual int isSortable() const
        {
        return 0;
        }

    virtual int isAssociation() const
        {
        return 0;
        }

    void _FAR *operator new( size_t s );
    virtual void forEach( iterFuncType, void _FAR * );
    virtual Object _FAR & firstThat( condFuncType, void _FAR * ) const;
    virtual Object _FAR & lastThat( condFuncType, void _FAR * ) const;
    virtual void printOn( ostream _FAR & ) const = 0;

    static Object _FAR *ZERO;

    static Object _FAR & ptrToRef( Object _FAR *p )
        { return p == 0 ? *ZERO : *p; }

    friend ostream _FAR& operator << ( ostream _FAR&, const Object _FAR& );

};

#define NOOBJECT  (*(Object::ZERO))

inline void Object::forEach( iterFuncType func, void _FAR *args )
{
    ( *func )( *this, args );
}

inline Object _FAR & Object::firstThat( condFuncType func,
                                        void _FAR *args
                                      ) const
{
   return (*func)( *this, args ) == 0 ? NOOBJECT : *this;
}

inline Object _FAR & Object::lastThat( condFuncType func,
                                       void _FAR *args
                                     ) const
{
    return Object::firstThat( func, args );
}

inline ostream _FAR& operator << ( ostream _FAR& out, const Object _FAR& obj )
{
    obj.printOn( out );
    return out;
}

inline int operator == ( const Object _FAR& test1, const Object _FAR& test2 )
{
    return (test1.isA() == test2.isA()) && test1.isEqual( test2 );
}

inline int operator !=( const Object _FAR& test1, const Object _FAR& test2 )
{
    return !( test1 == test2 );
}


class _CLASSTYPE Error : public Object
{

public:

    virtual classType isA() const
        {
        return errorClass;
        }

    virtual char _FAR *nameOf() const
        {
        return "Error";
        }

    virtual hashValueType hashValue() const
        {
        return ERROR_CLASS_HASH_VALUE;
        }

    virtual int isEqual( const Object _FAR & ) const
        {
        return 1;
        }

    virtual void printOn( ostream _FAR & ) const;

    void operator delete( void _FAR * );

};


inline void Error::printOn( ostream _FAR & out ) const
{
    out << nameOf() << '\n';
}

inline void Error::operator delete( void _FAR * )
{
    ClassLib_error( __EDELERROR );
}

#endif



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/*------------------------------------------------------------------------*/
/*                                                                        */
/*  QUEUE.H                                                               */
/*                                                                        */
/*  Copyright Borland International 1991                                  */
/*  All Rights Reserved                                                   */
/*                                                                        */
/*------------------------------------------------------------------------*/

#if !defined( __QUEUE_H )
#define __QUEUE_H

#if defined( TEMPLATES )

    #if !defined( __QUEUES_H )
    #include <Queues.h>
    #endif  // __QUEUES_H

    #define Queue   BI_TCQueueAsDoubleList
    #define PQueue  PBI_TCQueueAsDoubleList
    #define RQueue  RBI_TCQueueAsDoubleList
    #define RPQueue RPBI_TCQueueAsDoubleList
    #define PCQueue PCBI_TCQueueAsDoubleList
    #define RCQueue RCBI_TCQueueAsDoubleList

    _CLASSDEF( BI_TCQueueAsDoubleList )

    #define QueueIterator   BI_TCQueueAsDoubleListIterator
    #define PQueueIterator  PBI_TCQueueAsDoubleListIterator
    #define RQueueIterator  RBI_TCQueueAsDoubleListIterator
    #define RPQueueIterator RPBI_TCQueueAsDoubleListIterator
    #define PCQueueIterator PCBI_TCQueueAsDoubleListIterator
    #define RCQueueIterator RCBI_TCQueueAsDoubleListIterator

    _CLASSDEF( BI_TCQueueAsDoubleListIterator )

#else   // TEMPLATES

    #if !defined( __CLSTYPES_H )
    #include <ClsTypes.h>
    #endif  // __CLSTYPES_H

    #if !defined( __DEQUE_H )
    #include <Deque.h>
    #endif  // __DEQUE_H

    _CLASSDEF(Queue)

    class _CLASSTYPE Queue : public Deque
    {

    public:

        Object _FAR & get()
            {
            return Deque::getRight();
            }

        void put( Object _FAR & o )
            {
            Deque::putLeft( o );
            }

        virtual classType isA() const
            {
            return queueClass;
            }

        virtual char _FAR *nameOf() const
            {
            return "Queue";
            }

    private:

        Object _FAR & getLeft();
        Object _FAR & getRight();

        void putLeft( Object _FAR & );
        void putRight( Object _FAR & );

    };

#endif  // TEMPLATES

#endif  // __QUEUE_H



These are the headerfiles. I also do not understand how to use those template versions that are defined here.the classes Deque is almost similar to Queue but if needed I could post that too.
Deque is derived from class container which I'm posting in another post(word limit)


Okay, seeing Deque may or may not help further. I think from this:

1
2
3
4
5
6
7
8
9
10
11
12
13
class abc :public Queue
{public: int a;
   abc(int a1)
  {a=a1;
  }
};

abc q;
for (int i=0;i<5;i++)
  q.add(i);

for (i=0;i<5;i++)
 cout<<q.get(); 


You probably need to make abc an Object rather than a Queue like this:


1
2
3
4
5
6
class abc :public Object
{public: int a;
   abc(int a1)
  {a=a1;
  }
};


And I suspect that you need to use the put() method rather than add(); I have no idea which class is supplying add() into the mix, but Queue seems to want a put();

1
2
3
4
5
6
7
8
9
10
11
Queue q;

for (int i=0;i<5;i++)
{
   abc a(i);
  q.put(a); // put a new abc (which is an Object) into the Queue q.

for (i=0;i<5;i++)
 cout<<q.get(i);   // I am not sure what you expect this to do.

// C++ will be looking at this as an Object (rather than an abc) 

Last edited on
Its hard to know for sure but I suspect Queue and Object are meant to be used a bit like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MyClass : public Object
{
public:
	void func();
};

Queue q;

MyClass m1;
MyClass m2;
MyClass m3;

q.put(m1);
q.put(m2);
q.put(m3);

MyClass& m1ref = dynamic_cast<MyClass&>(q.get());
MyClass& m2ref = dynamic_cast<MyClass&>(q.get());
MyClass& m3ref = dynamic_cast<MyClass&>(q.get());


Last edited on
Galik,

regarding the second post, "dynamic cast " is not a valid operation in turbo c++.
regarding the first post,

1
2
3
4
5
6
7
for (i=0;i<5;i++)

 cout<<q.get(i);   // I am not sure what you expect this to do.

// C++ will be looking at this as an Object (rather than an abc) 



I am trying to access the integer' a' defined after taking it back from the queue. I made class abc derived from class Queue because, object is an abstract class and I would have to write all the functions from scratch. But , Queue is derived (indirectly) from object so all the virtual functions are already defined.
Okay then try this:

1
2
3
4
for(int i = 0; i < 5; ++i)
{
   std::cout << ((abc) q.get()).a;
}


Basically what q.get() does is return a reference to an Object. But you put in a subclass of Object called abc.

So when you use get() to remove your Object (which you know is really an abc) you need to cast it to an abc before you can access its data:

so, q.get(); returns an Object. BUT (abc) q.get(); tells the compiler that the Object is really an abc.

So you can take that whole expression ((abc) q.get()) and treat it just like an abc: ((abc) q.get()).a to access data member a.
Last edited on
Tried that. Got error

Could not find match for abc::abc(Object)
Sorry, try this:

std::cout << ((abc&) q.get()).a;
i got some wierd large -ve values, random ones.
Pages: 12