使用g ++ 4.2.1编译此代码:
struct S { };
template<typename T> struct ST { };
template<typename BaseType>
class ref_count : private BaseType { };
template<typename RefCountType>
class rep_base : public RefCountType { };
class wrap_rep : public rep_base<ref_count<S> > {
typedef rep_base<ref_count<S> > base_type; // line 11
};
Run Code Online (Sandbox Code Playgroud)
我明白了:
bug.cpp:1: error: ‘struct S’ is inaccessible
bug.cpp:11: error: within this context
Run Code Online (Sandbox Code Playgroud)
但是,如果我更改wrap_rep要使用的类ST:
class wrap_rep : public rep_base<ref_count< ST<int> > > {
typedef rep_base<ref_count< ST<int> > > base_type;
};
Run Code Online (Sandbox Code Playgroud)
它编译得很好.或者,如果我将原始代码更改为: …
我正在读约瑟夫·阿尔巴巴里和本·阿尔巴巴里的书"简而言之的C#4.0".从那里我发现访问修饰符的主题限制.第91页,主题"访问修饰符的限制".
从书中引用.
编译器会阻止任何不一致的访问修饰符的使用.例如,子类本身可以比基类更难访问,但不能更多
所以这说明基类应该与子类相同或更易于访问.因此,如果基类是内部的,那么子类应该是私有的或内部的.如果基类是私有的,而子类是公共的,那么将生成编译时错误.在Visual Studio中尝试这个时,我发现了一些奇怪的行为.
尝试1:Base是私有的,子类是私有的(Works,正确的行为)如果两者都是内部的,那么它也有效.
private class A { }
private class B : A { } // Works
Run Code Online (Sandbox Code Playgroud)
尝试2:Base是私有的,子类是public或internal(这是失败的,正确的行为)
private class A { }
public class B : A { } // Error
Run Code Online (Sandbox Code Playgroud)
尝试3:Base是内部的,sub是公共的(这是有效的,但它应该失败.因为Base比子类更难访问
internal class A { }
public class B : A { } // Works, but why
Run Code Online (Sandbox Code Playgroud)
现在我的问题是为什么试试3没有失败?子类是公共的,比内部的基类更容易访问.即使这本书说这应该失败.但Visual Studio成功编译了这个.这应该工作与否?
编辑:
我在VS中创建了一个新的控制台项目.在Program.cs中,我添加了我的代码.这是Program.cs文件的完整代码.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace ConsoleApplication
{
class Program
{
internal class A { }
public class B …Run Code Online (Sandbox Code Playgroud) 让我们看看以下代码:
class A{
protected:
int _val;
public:
A(){printf("calling A empty constructor\n");}
A(int val):_val(val){printf("calling A constructor (%d)\n", val);}
};
class B: virtual public A{
public:
B(){printf("calling B empty constructor\n");}
B(int val):A(val){printf("calling B constructor (%d)\n", val);}
};
class C: public B{
public:
C(){printf("calling C empty constructor\n");}
C(int val):B(val){printf("calling C constructor (%d)\n", val);}
};
int main(void) {
C test(2);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
calling A empty constructor
calling B constructor (2)
calling C constructor (2)
Run Code Online (Sandbox Code Playgroud)
有人可以向我解释为什么没有任何参数调用A类构造函数?如果我希望B类从A虚拟继承,我还能如何"修复"这种行为?(如果继承不是虚拟的 - 样本工作正常)
我在理论上认为这个问题的答案是肯定的.
但是,在实践中,我的编译器(VS2010)似乎并没有在以下情况下抱怨:我有一个抽象基类提供了一些通用接口(但没有数据成员)以及从中派生的各种子类和子类.
class Base
{
public:
Base() {}
virtual ~Base() {}
virtual void interfaceFunction1() = 0;
virtual void interfaceFunction2() = 0;
private:
Base(const Base&); // all derived classes should be uncopyable
Base& operator=(const Base&);
// no data members
};
Run Code Online (Sandbox Code Playgroud)
我的编译器发现甚至在子子类或子子类中实现完整拷贝构造函数也没有问题.
如何确保从Base派生的每个类都是不可复制的?
编辑:如果我理解得很好,这正是Scott Meyers在Effective C++(第3版,2005)第6项中解释的他对类的想法Uncopyable(仅扩展到完整的接口类).是什么让他的想法发挥作用?(我知道他私下继承,但这不应该造成问题)
考虑以下C++代码,
template <typename Derived>
struct A
{
bool usable_;
};
template <typename Derived>
struct B : A< B<Derived> >
{
void foo()
{
usable_ = false;
}
};
struct C : B<C>
{
void foo()
{
usable_ = true;
}
};
int main()
{
C c;
}
Run Code Online (Sandbox Code Playgroud)
我有编译错误:在成员函数中void B<Derived>::foo():
template_inherit.cpp:12:错误:在此范围内未声明'useful_'.
这是为什么 ?任何好的修复?
我搜索过但无法找到解决问题的方法.我的场景非常简单:
public class A
{
public virtual void MethodOne()
{
Console.log( "A" );
}
}
public class B : A
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "B" );
}
}
public class C : B
{
public override void MethodOne()
{
base.MethodOne();
Console.log( "C" );
}
}
Run Code Online (Sandbox Code Playgroud)
我想要做的是有一个C类实例(我们将它命名为'instanceC')调用它的父类和它的祖父母的重写方法.所以我期待这个:
instanceC.MethodOne();
// Output:
// "A"
// "B"
// "C"
Run Code Online (Sandbox Code Playgroud)
但是我得到了这个:
instanceC.MethodOne();
// Output
// "A"
// "C"
Run Code Online (Sandbox Code Playgroud)
B类的方法被跳过了.这不可能吗?我认为这是继承/多态的全部要点.提前致谢!
如果我有一个基类通过构造函数依赖注入服务:是否可以在不使用的情况下声明子类的构造函数: base (params)?
public MyBaseClass
{
private IServiceA _serviceA;
private IServiceB _serviceB;
private IServiceC _serviceC;
public MyBaseClass(null, null, null)
public MyBaseClass(IServiceA serviceA, IServiceB serviceB, IServiceC serviceC)
{
_serviceA = serviceA;
_serviceB = serviceB;
_serviceC = serviceC;
}
}
Run Code Online (Sandbox Code Playgroud)
并且注入了一些额外依赖项的子类:
public MySubClassA : MyBaseClass
{
private IServiceD _serviceD;
public MySubClassA (null, null, null, null)
public MySubClassA (IServiceA serviceA, IServiceB serviceB,
IServiceC serviceC, IServiceD serviceD)
: base (serviceA, serviceB, serviceC)
{
_serviceD = serviceD;
}
}
Run Code Online (Sandbox Code Playgroud)
这里的问题是我有多个子类,现在只有10个左右,但数量会增加.每次我需要向基类添加另一个依赖项时,我必须遍历每个子类并在那里手动添加依赖项.这个手工工作让我觉得我的设计有问题.
那么是否可以MyBaseClassA在子类的构造函数中声明构造函数而不需要基类所需的服务?例如,以便构造函数 …
c# dependency-injection subclass inversion-of-control base-class
使用clang 3.4(trunk),有没有办法用常量表达式计算基类的位移?
struct A { int a; };
struct B { int b; };
struct C: A, B {};
// cannot access base class of null pointer:
constexpr auto c_b_address = /*(size_t)*/ &(B&) *(C*)nullptr;
Run Code Online (Sandbox Code Playgroud) 我已经用Java编程了近两年但我现在更多地转向Web编程,因此转向Javascript,或者我的情况转向Dart.对于我正在研究的项目,我希望有抽象基类,就像我在Java中一样.我一直在网上看,但我在Dart的抽象课上找不到任何东西.我只在mixins上的dartlang网站上发现了这篇文章,在一个例子中,它使用了一个类的abstract关键字.但我真的不了解mixins原理.
有人可以将这个简单的Java抽象基类示例转换为Dart,以便我可以基本了解如何在Dart中完成它吗?该示例涵盖抽象基类(当然,使用抽象方法),多态,转换对象,方法重载(在本例中是构造函数),调用超级构造函数并调用重载自己的构造函数.
// Abstract base class
abstract class Vehicle {
protected final int maxSpeed;
protected int speed;
Vehicle() {
this(0);
}
Vehicle(int maxSpeed) {
this.maxSpeed = maxSpeed;
speed = 0;
}
public int getMaxSpeed() {
return maxSpeed;
}
abstract void accelerate();
abstract void brake();
}
// Subclass of Vehicle, the abstract baseclass
class Car extends Vehicle {
public final int doors;
Car(int maxSpeed, …Run Code Online (Sandbox Code Playgroud) 我们有一个包,我们希望将其从 python 转换为 kotlin,以便能够使用该包迁移系统。
在包中有一组类,它们都是公共基类的变体或“风味”。
大多数代码都在基类中,它具有大量可选参数。所以考虑:
open class BaseTree(val height:Int=10,val roots:Boolean=true, //......还有很多!!
class FruitTree(val fruitSize, height:Int=10, roots:Boolean=true,
// now need all possible parameters for any possible instance
):BaseTree(height=height, roots=roots //... yet another variation of same list
Run Code Online (Sandbox Code Playgroud)
代码实际上并不是树,我只是认为这是传达想法的一种简单方式。基类有大约 20 个参数,大约有 10 个子类,每个子类实际上需要重复来自基类的参数列表的相同两个变体。如果参数列表发生变化,那真是一场噩梦!
那些来自 Java 背景的人可能会评论“20 个参数太多了”,可能会错过这是可选参数,影响这方面设计的语言特性。20个必需参数会很疯狂,但10个甚至20个可选参数并不少见,例如查看sqlalchemy表。
在python中,你可以调用一个基类构造函数:
def __init__(self, special, *args, **kwargs):
super().__init(*args, **kwargs) # pass all parameters except special to base constructor
Run Code Online (Sandbox Code Playgroud)
有没有人知道一种技术,使用不同的方法(也许使用接口或其他方法?)来避免为每个子类一遍又一遍地重复这个参数列表?
base-class ×10
c++ ×5
inheritance ×4
c# ×3
private ×2
.net ×1
c++11 ×1
c++14 ×1
class ×1
constexpr ×1
constructor ×1
dart ×1
java ×1
kotlin ×1
name-lookup ×1
oop ×1
subclass ×1
templates ×1