I have a class called Scanner which casts rays into a 3d scene and records the resulting intersections. It has the following type of properties:
Location (a 3d point)
Forward (a 3d vector)
Up (a 3d vector)
min/max angle (the bounds of where to cast rays)
theta/phi step (the directions of the rays)

I've been saving the results in a class called Scan. But I'd like for a Scan object to know everything about the Scanner that created it. So this doesn't fit the "is a" paradigm of OOP inheritance - so these classes are not related in my current setup. How would you structure these? It doesn't really make sense for a Scan to exist without having come from a Scanner, so my first thought was just to make

class Scanner
{
Scan TheScan;
};

But then for some functions it doesn't make sense to pass only TheScan to them because it needs some info from the Scanner, but it also doesn't make intuitive sense to pass the whole Scanner object:

double ComputeAverageDistance(const Scan &TheScan)
{
//for each intersection, find the distance to the scanner
}

In that example - the location of the scanner would need to be known to compute the distance. Passing the whole scanner seems weird: ComputeAverageDistance(const Scanner &TheScanner) .

Have I explained my concern well at all?

Thanks,

Dave

Flip your first thought around. If Scan has a pointer to a Scanner, the constructor can take an argument of this from the Scanner object generating the Scan object:

class Scanner;

class Scan
{
    Scanner *_scanner;
public:
    Scan(Scanner *scanner): _scanner(scanner) {}
};

class Scanner
{
public:
    Scan GenerateScan()
    {
        return Scan(this);
    }
};

That is what I gathered from your question. But as long as you have a Scanner, any factory method can pass a pointer to it as the argument for a Scan constructor call.

Thanks Tom Gunn. Can anyone else comment if they would do this the same way Tom recommended?

daviddoria,
Think about nested class,

class Scanner
{
     private:
           class Scan
           {
           };
     public:
     Scan sc;
     ....
};

Ok, it's something to keep in mind - but I don't see how that helps in this situation over just having a Scan member variable inside Scanner?

You can declare any of those 2 classes into the other one, as long as you have the respective function returning and using the right data. To make a reference to the thread name, I would declare the scanner class as a base class for scan class, so the scan class can use the necessary data from the scanner class.

Yea that's kinda what I was thinking, but it doesn't follow the "is a" OOP idea, but maybe sometimes you don't have to follow that?

Well, to my understanding being able to create a base/child relation between classes forms part of the main idea of object oriented programming. If I got the wrong idea, by all means, let me know.

I have a class called Scanner which casts rays into a 3d scene and records the resulting intersections.
...

I've been saving the results in a class called Scan. But I'd like for a Scan object to know everything about the Scanner that created it.
...

Have I explained my concern well at all?

I don't think so, sorry.

My mental image of this is that Scanner is doing stuff, and making records of what it finds as records that are Scan objects.

If this were so, it would be simple: Scan is an array/list/whatever of Scan's and that's that.

You infer that Scan's are active objects, not passive records.

The next most obvious step is to make the constructor of Scan have an arg which is a Scanner* "parent" pointer; there are issues there (consider Scanner calling Scan which calls the same Scanner back again) but if you're careful it can be done well.

However, I can't really see where you're going. Could you elaborate?

Ruth

You are exactly correct - Scanner is doing stuff and Scan is a passive "record". The dilemma is in that some of the properties are common to both, e.g. number of points, the location the scan was taken from (which is currently the Location of the Scanner and the ScannerLocation of the Scan). There are about 10 of this type of "shared" property that I have been quite annoyingly copying into the Scan object each time one is created.

Does that clear things up?

There are about 10 of this type of "shared" property that I have been quite annoyingly copying into the Scan object each time one is created.

If Scan has a pointer to the Scanner parent, why make a copy of the properties at all? You can access them through the parent pointer at only the cost of an extra level of indirection.

This article has been dead for over six months. Start a new discussion instead.