[Gdal-dev] GDALDataset as a Base Class

Mateusz Loskot mateusz at loskot.net
Tue Aug 29 22:06:47 EDT 2006


Matt Hanson wrote:
> I'm writing a derived class of GDALDataset and I'm not sure how to
> implement the constructor. I want to be able to take in a filename
> as an argument, and I should then have to explicitly call the
> GDALDataset ctor.

Simplified answer is that you can not call constructor directly.
Second, you can't call constructor especially on already instantiated
object. Constructors are called during object instantiation.

> But GDALDataset doesn't have a public constructor
> that I can see as it uses GDALOpen and a cast to create it.

This is not the problem here with the GDALDataset, because GDALDataset
ctor is protected what makes it callable from subclasses.
The problem is that GDALDataset is unusable for your concept,
because it does not take any parameters you could use, for example
image file descriptor, etc.

Here is example of "calling" base class ctor - only possible
through initialization list.

//////////////////////////////////////////////
#include <iostream>

class Base
{
public:
    virtual ~Base() {}
    int get() const { return id_; }

protected:
    Base(int id) : id_(id) {}

private:
    int id_;

};

class A : public Base
{
public:
    A(int a, int b) : Base(a), other(b) {}
    int other;

};

int main()
{
    A a(12, 103);

    std::cout << "a.get(): " << a.get() << std::endl;
    std::cout << "a.other: " << a.other << std::endl;

    return 0;
}
//////////////////////////////////////////////


> I've tried this line in the ctor:
> *this = (GDALDataset *)GDALOpen( FileName(), GA_ReadOnly );

It won't work, because:
1. C++ Standard/ 9.3.2 The this pointer/ 1 says:
"(...)the keyword this is a non-lvalue expression whose value is the
address of the object for which the function is called."

but in C++ you can not assign anything to non-lvalue.

2. 'this pointer' cannot be changed while the object exists

> Along with a copy ctor:
> 
> GSImage(GDALDataset* ds) {
> 
> *this  = ds;
> 
> }
> 
> which compiles but of course doesn't work. I didn't think it would,
> but I'm not exactly sure why.

This copy constructor is invalid.

C++ Standard / 12.8 Copying class objects / 2 says:

"A non-template constructor for class X is a copy constructor if its
first parameter is of type X&, const X&, volatile X&
or const volatile X&, and either there are no other parameters or else
all other parameters have default arguments
Example: X::X(const X&) and X::X(X&,int=1) are copy constructors."


the same rule applies to assignment operator.
BTW, if you add copy ctor, then you have to add assignmet operator as well.


GSImage(GDALDataset const& ds)
{
   if (this != &ds)
   {
      // copy ds object members values to this members values
   }
}

BTW, (*this) is a reference, not a pointer.

> Any ideas on what my derived class
> constructor should look like then?

I would use "named constructor idiom" and factory method:
Here is the concept in very short:

class GSImage : public GDALDataset
{
public:
  static GSImage* Create(const char* file)
  {
     return static_cast<GSImage*>( GDALOpen(file, GA_ReadOnly ) );
  }
};

GSImage* pImage = GSImage::create("myfile.png");


Cheers
-- 
Mateusz Loskot
http://mateusz.loskot.net



More information about the Gdal-dev mailing list