只允许消费者通过派生类访问基类成员。

huangapple go评论144阅读模式
英文:

cpp: permit base member access only via derived by consumer

问题

我有一个应用程序,其中Base是一个工厂类,用于根据模板对创建的对象进行不同的创建。然而,只有非常特定(可计数的无限)数量的模板对是有意义的。对于每个有意义的模板对,我都有一个(有时是有模板的)派生工厂类。由于需要选择可行的正确模板对,使用Base Factory容易出错。

我的问题是:如何防止消费者直接使用Base Factory?

template<typename T1, typename T2>
class Base{
  Base()=delete;
public:
  // 许多公共静态例程
  T1 static foo(){ return 1; }
  T2 static bar(){ return 2; }
};

template<typename T1>
class Derived: public Base<T1,float>{
  // 希望很少的代码,或者根本没有,就像现在一样。
};

int main(){ // main是消费者
  Base<int,float>::foo(); // 阻止
  Derived<int>   ::foo(); // 允许
}

我希望编译器在main中拒绝/抛出/报错带有注释“prevent”的行。我希望Base<..>::foo和Base<..>::bar不直接可访问消费者,除非通过Derived<..>的访问。我曾希望“虚拟”概念可以用于此目的;但它不自然地从非静态到静态情况转移。

英文:

I have an application where Base is a factory class for objects that shall be created differently depending on a template pair. However, only very particular (countable infinite) number of template pairs make sense. For each of sensible pair, I have a (sometimes) templated Derived Factory class. The use of Base Factory is error prone due to the need for feasible correct choice of the template pair.

My question is: How can I prevent a consumer from using the Base Factory directly?

template&lt;typename T1, typename T2&gt;
class Base{
  Base()=delete;
public:
  // many public static routines
  T1 static foo(){ return 1; }
  T2 static bar(){ return 2; }
};

template&lt;typename T1&gt;
class Derived: public Base&lt;T1,float&gt;{
  // hopefully very little code, or none at all, as of now.
};

int main(){ // main is the consumer
  Base&lt;int,float&gt;::foo(); // prevent
  Derived&lt;int&gt;   ::foo(); // permit
}

I want the compiler to reject/thow/err the line with comment "prevent" in main. I want Base<..>::foo and Base<..>::bar not directly accessible by a consumer unless via access through Derived<..>. I had hoped that the virtual concept could be used for that purpose; however it does not transfer naturally from the non-static to the static case.

答案1

得分: 1

你可以将foo方法设为protected,然后通过Derived类使用publicusing语句来暴露它:

template<typename T1, typename T2>
class Base {
	Base() = delete;
protected:
	T1 static foo() { return 1; }
	T2 static bar() { return 2; }
};

template<typename T1>
class Derived : public Base<T1, float> {
public:
	using Base<T1, float>::foo;
};

int main() { // main is the consumer
	Base<int, float>::foo(); // 阻止
	Derived<int>::foo(); // 允许
}

Live demo - Godbolt

英文:

You can make the foo method protected, and expose it via the Derived class with a public using statement:

template&lt;typename T1, typename T2&gt;
class Base {
	Base() = delete;
protected:
	T1 static foo() { return 1; }
	T2 static bar() { return 2; }
};

template&lt;typename T1&gt;
class Derived : public Base&lt;T1, float&gt; {
public:
	using Base&lt;T1, float&gt;::foo;
};

int main() { // main is the consumer
	Base&lt;int, float&gt;::foo(); // prevent
	Derived&lt;int&gt;   ::foo(); // permit
}

Live demo - Godbolt

huangapple
  • 本文由 发表于 2023年8月10日 20:01:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/76875574.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定