PDA

View Full Version : ambiguous access error with QObjects that implement Interfaces



scarleton
24th August 2010, 14:52
The model is two classes, base and derived, and both have corresponding interfaces, Ibase and Iderived. When I go to implement the derived class, I am getting ambiguous access errors, I am wondering if the mod compiler is messing me up. Here is the base interface (ICSData):



__interface ICSData
{
virtual CSBase* state() = 0;

virtual bool Load() = 0;
virtual bool Unload() = 0;
virtual bool Connect() = 0;
virtual bool Disconnect() = 0;

virtual int GetBatteryLevel() = 0;
virtual bool AcquireImage(long itemId, const QString& filepath) = 0;

virtual void onCameraDisconnected(long srcID) = 0;
virtual void onCameraConnected(long srcID) = 0;
virtual void onBatteryLevelChange(int percentage) = 0;
virtual void onImageCaptured(long itemId, QString name, QDateTime captureTime) = 0;
virtual void onProcessReset(long itemId, int maximum) = 0;
virtual void onProcessSetValue(long itemId, int value) = 0;

virtual const QString& lastError() const = 0;
virtual void setLastError(const QString& value) = 0;
};


And here is the base class:



class CSData : public QObject, public ICSData
{
Q_OBJECT

public:
CSData(QObject *parent);
~CSData();

CSBase* state() { return _state; }
void setState(CSBase* val) { _state = val; }

CSBase* csUnloaded();
CSBase* csInitialized();
CSBase* csConnected();
CSBase* csCaptured();

virtual void onCameraDisconnected(long srcID);
virtual void onCameraConnected(long srcID);
virtual void onBatteryLevelChange(int percentage);
virtual void onImageCaptured(long itemId, QString name, QDateTime captureTime);
virtual void onProcessReset(long itemId, int maximum);
virtual void onProcessSetValue(long itemId, int value);

virtual QMessageBox::StandardButton uiRequest(const QString& prompt, const QString& detail, QMessageBox::StandardButtons buttons, QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);

virtual const QString& lastError() const;
virtual void setLastError(const QString& value);

signals:
void cameraDisconnected(long srcID);
void cameraConnected(long srcID);
void batteryLevelChange(int percentage);
void imageCaptured(long itemId, QString name, QDateTime captureTime);
void processReset(long itemId, int maximum);
void processSetValue(long itemId, int value);

protected:
QString _lastError;

private:
CSBase * _state;

CSUnloaded * _csUnloaded;
CSInitialized * _csInitialized;
CSConnected * _csConnected;
CSCaptured * _csCaptured;
};


These are the methods causing problems:

onCameraDisconnected
onCameraConnected
onBatteryLevelChange
onImageCaptured
onProcessReset
onProcessSetValue
uiRequest
lastError
setLastError

For the record, I MUST have the interfaces because of circular references elsewhere in the code.

Sam

leoalvesmachado
24th August 2010, 15:57
Both interfaces have the same method's name? Maybe that's why it happens.
I'm not very good with C++ syntax, but I would create a "super interface" containing the common methods to avoid it. Another option would be to use namespaces to differentiate the methods...

Hope I could help

Lykurg
24th August 2010, 16:17
musn't you skip the virtual in your implementation?

scarleton
24th August 2010, 16:24
Actually the fist code snippet (__interface ICSData) is the interface and the second code snippet (class CSData) is the class implementation of the interface. For this reason, the method names along with the calling convention of the methods must be 100% identical so that the implementation does actually implement the interface.

I guess I should have been more clear, what I am *NOT* showing is the derived Interface or the derived class. I don't believe they are very relevant. I am guessing that the moc compiler is keying off Qt specific things. I am seeing three possible things the moc compiler might be keying off to change the calling convention:

1: I am wondering about the auto-connection facilities, the fact the moc compiler wires up single/slots automatically using the convention of void on_<widget name>_<signal name>(<signal parameters>). Is that coming into play because some of the methods begin with the two chars on?

2: Maybe the moc compiler is doing something to the lastError() because it looks like a property.

3: Maybe the moc compler is mucking up the uiRequest because of all the Qt types in the calling convention.

I am just guessing.

Sam

scarleton
24th August 2010, 16:28
musn't you skip the virtual in your implementation?
I have tried it both way and continue to get the same error. If I am not mistaken on derived classes the keyword virtual has no effect, but also does no harm. It is just required on the lowest level instance to create the vtable entry for the function, though it is nice to put on derived classes for documentation purposes (or in my case where it use to be the base class until I added the interface).