【发布时间】:2022-02-01 15:10:21
【问题描述】:
如果我有这样的事情:
mytemplates.h
#ifndef MYTEMPLATES_H
#define MYTEMPLATES_H
#include <iostream>
#include <memory>
#include <string>
class BaseClass;
// Alias (non-working) version:
//class DerivedClass1;
namespace MyTemplates
{
typedef std::unique_ptr<BaseClass> object_up;
template<typename SomeDerivedClass>
object_up createFromIntFloat(int intParam, float floatParam)
{
SomeDerivedClass *newObject_raw = new SomeDerivedClass(intParam, floatParam);
object_up uniqueObject {newObject_raw};
std::cout << "createFromIntFloat." << "\n";
return uniqueObject;
}
// Alias (non-working) version:
//using createFromIntFloatPtrType = object_up(*)(int intParam, float floatParam);
template<typename SomeDerivedClass>
object_up createFromString(std::string stringParam)
{
SomeDerivedClass *newObject_raw = new SomeDerivedClass(stringParam);
object_up uniqueObject {newObject_raw};
std::cout << "createFromString." << "\n";
return uniqueObject;
}
// Alias (non-working) version:
//using createFromStringPtrType = object_up(*)(std::string stringParam);
// Alias (non-working) version:
// createFromStringPtrType createDerivedClass1 = createFromString<DerivedClass1>;
}
#endif // MYTEMPLATES_H
基类.h
#ifndef BASECLASS_H
#define BASECLASS_H
class BaseClass
{
protected:
BaseClass(){};
};
#endif // BASECLASS_H
派生类1.h
#ifndef DERIVEDCLASS1_H
#define DERIVEDCLASS1_H
#include "baseclass.h"
#include "mytemplates.h"
class DerivedClass1 : public BaseClass
{
std::string stringParam;
protected:
DerivedClass1(std::string aStringParam) : BaseClass(), stringParam(aStringParam) {};
// Alias (non-working) version:
// friend MyTemplates::object_up MyTemplates::createDerivedClass1(std::string stringParam);
// Non-alias version:
friend MyTemplates::object_up MyTemplates::createFromString<DerivedClass1>(std::string stringParam);
};
#endif // DERIVEDCLASS1_H
main.cpp
#include "mytemplates.h"
#include "derivedclass1.h"
int main(int argc, char *argv[])
{
// Alias (non-working) version:
// MyTemplates::object_up uniqueClass1 = MyTemplates::createDerivedClass1("creation info for class 1");
// Non-alias version:
MyTemplates::object_up uniqueClass1 = MyTemplates::createFromString<DerivedClass1>("creation info for class 1");
}
我想在上述代码上创建某种别名,例如 Alias(非工作)版本,以便我可以使用此别名 - createDerivedClass1 - 两者在 main.cpp 中的直接调用和 derivedclass1.h
中的友元声明中如何将上面的代码从非别名版本更改为别名版本并使其工作?
【问题讨论】:
-
createDerivedClass1是一个函数指针,所以friend声明是错误且无用的。所以你的全局变量应该只定义一次(或者是inline)。 -
@Jarod42 那么如何让 createFromString
访问 DerivedClass1 受保护的 ctor? -
@Jarod42 哦,我相信我现在看到了:我保留了朋友声明的原始(非别名版本)并在其他地方使用别名版本,对吧?
-
createDerivedClass1(可能是const/constexpr)只是“调用”createFromString<DerivedClass1>,所以不需要额外的访问权限。您可以取消注释除朋友声明之外的所有内容。 (并为您的全局修复 ODR)。