Implicit Argument Passing of Super from Method Defined by Define_Method() Is Not Supported

Implicit argument passing of super from method defined by define_method() is not supported

The super above passed all parameters (see this recent question).

As the error message states, you must here "specify all arguments explicitly". Replace super with super(label, *args).

Why I can not call super in define_method with overloading method?

The error message is quite descriptive. You need to explicitly pass arguments to super when you call it inside of define_method block:

mem[args] = super(*args)

Accessing fields/methods/constructors of an abstract class in its subclass

Is the super() call needed or even valid?

It is not needed, but it is valid. All constructor must call a superclass constructor, either explicitly as you have done, or implicitly. If super(); wasn't explicitly included, the compiler would have inserted an implicit call for you.

Can an abstract class even have a constructor given that it can't be instantiated?

Yes, an abstract class can have a constructor. It needs to be called by any subclass constructor.

Is the keyword "this" necessary in this example concerning this.name?

"this" is not necessary here, because there is no local variable or parameter in scope, of the same name, that would hide the instance variable name.

What is the play() overriding here?

It is implementing the abstract play() method. The @Override annotation can be used to indicate that the method overrides or implements a superclass or interface method. Because ElectricGuitar is not abstract, it does need to implement play(), so @Override is not strictly necessary here. However, it is good practice to include this annotation an all methods that are intended to override/implement a method, so that a spelling mistake or typo doesn't mean that the method accidentally doesn't override another method.

If the Instrument class, StringedInstrument class, and ElectricGuitar class all specified fields called "name" and each had specified constructors (if allowed) how would each name or constructor be accessed in the ElectricGuitar class definition?

You cannot directly access fields that are hidden above the superclass. You can access StringedInstrument's name with super.name, but you cannot access Instrument's name with super.super.name, because you can't "chain" super references. To access them directly, name them differently.

You can however provide getter methods, differently named, in each class, that will provide access to each class's name method.

Why can templates only be implemented in the header file?

Caveat: It is not necessary to put the implementation in the header file, see the alternative solution at the end of this answer.

Anyway, the reason your code is failing is that, when instantiating a template, the compiler creates a new class with the given template argument. For example:

template<typename T>
struct Foo
{
T bar;
void doSomething(T param) {/* do stuff using T */}
};

// somewhere in a .cpp
Foo<int> f;

When reading this line, the compiler will create a new class (let's call it FooInt), which is equivalent to the following:

struct FooInt
{
int bar;
void doSomething(int param) {/* do stuff using int */}
}

Consequently, the compiler needs to have access to the implementation of the methods, to instantiate them with the template argument (in this case int). If these implementations were not in the header, they wouldn't be accessible, and therefore the compiler wouldn't be able to instantiate the template.

A common solution to this is to write the template declaration in a header file, then implement the class in an implementation file (for example .tpp), and include this implementation file at the end of the header.

Foo.h

template <typename T>
struct Foo
{
void doSomething(T param);
};

#include "Foo.tpp"

Foo.tpp

template <typename T>
void Foo<T>::doSomething(T param)
{
//implementation
}

This way, implementation is still separated from declaration, but is accessible to the compiler.

Alternative solution

Another solution is to keep the implementation separated, and explicitly instantiate all the template instances you'll need:

Foo.h

// no implementation
template <typename T> struct Foo { ... };

Foo.cpp

// implementation of Foo's methods

// explicit instantiations
template class Foo<int>;
template class Foo<float>;
// You will only be able to use Foo with int or float

If my explanation isn't clear enough, you can have a look at the C++ Super-FAQ on this subject.

Object-orientation in C

C Object System (COS) sounds promising (it's still in alpha version). It tries to keep minimal the available concepts for the sake of simplicity and flexibility: uniform object oriented programming including open classes, metaclasses, property metaclasses, generics, multimethods, delegation, ownership, exceptions, contracts and closures. There is a draft paper (PDF) that describes it.

Exception in C is a C89 implementation of the TRY-CATCH-FINALLY found in other OO languages. It comes with a testsuite and some examples.

Both by Laurent Deniau, which is working a lot on OOP in C.



Related Topics



Leave a reply



Submit