• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: STL vector not working
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: STL vector not working


  • Subject: Re: STL vector not working
  • From: "Ken Thomases" <email@hidden>
  • Date: Sun, 13 Oct 2002 11:53:07 -0500
  • Priority: normal

On 12 Oct 2002, at 7:21, Todd Heberlein <email@hidden> wrote:
> On Friday, October 11, 2002, at 04:27 PM, Arthur Clemens wrote:
>
> > @interface Database : NSObject
> > {
> > std::vector<int> _usedNumbersArray;
> > std::vector<int> _recycledNumbersArray;
> > }
>
> C++ objects seem to need to be declared as pointers.

Well, just FYI, what's actually going on is that the Objective-C
runtime doesn't make any effort to call C++ constructors on the
objects/instances it creates or, consequently, on instance variables
which might be C++ objects.

So, the result from +alloc is similar to what you would get if a C++
program did the following:

class Foo
{
public:
std::vector<int> someVector;
};

Foo* pFoo = (Foo*) calloc(1, sizeof(Foo)); // Ack! Broken.

(Note that calloc is like malloc followed by memset-to-zero.) The
memory pointed to by pFoo isn't really an instance of class Foo
because it hasn't been properly constructed. As a result,
pFoo->someVector isn't really a proper vector<int> either.

> Try the following definitions instead:
>
> std::vector<int> *_usedNumbersArray;
> std::vector<int> *_recycledNumbersArray;
>
> and then in an init method, do something like this:
>
> - (id)init
> {
> if (self = [super init]) {
> _usedNumbersArray = new std::vector<int>;
> _recycledNumbersArray = new std::vector<int>;
> ...
> }
> return self;
> }

Of course, if you do this don't forget to delete the two fields in
-dealloc.

Since the root problem is failure to call the objects' constructors,
there is another solution which avoids extraneous heap allocation.
Revert to the original, non-pointer declarations of the members and
use placement-new to construct them in place. In -dealloc directly
call their destructor. Like so:

...
std::vector<int> _usedNumbersArray;
std::vector<int> _recycledNumbersArray;
...

- (id)init
{
if (self = [super init]) {
// Construct C++ ivars in their already-allocated storage
new (&_usedNumbersArray) std::vector<int>;
new (&_recycledNumbersArray) std::vector<int>;
...
}
return self;
}

- (void)dealloc
{
// Destruct C++ ivars without deallocating their storage
_usedNumbersArray.~vector();
_recycledNumbersArray.~vector();
...
[super dealloc]
}


Personally, as a C++ programmer who sees much to like in Objective-C,
I would be interested if Apple and the gcc-folks were to improve
Objective-C++ by fixing these sorts of gaps. The construction/
destruction issue and unifying the exception handling mechanisms are
the two big gaps I'm aware of, and I think they are both eminently
solvable without "tainting" Objective-C.

Ken
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Prev by Date: [myMatrix addColumn] but NSMatrix doesn't show Cells
  • Next by Date: class error for 'ASKNibObjectInfoManager': class not loaded
  • Previous by thread: Re: STL vector not working
  • Next by thread: NSView drawRect: QuickDraw, CoreGraphics, OpenGL ?
  • Index(es):
    • Date
    • Thread