我有一个类的抽象类,Room它有子Family和Standard,我创建了room = new ArrayList<Room>();一个内部Hostel类.我有一个方法来添加一个房间到ArrayList;
public String addRoom(String roomNumber, boolean ensuite)
{
if (roomNumber.equals(""))
return "Error - Empty name field\n";
else
room.add( new Room(roomNumber,ensuite) );
return "RoomNumber: " + roomNumber + " Ensuite: " + ensuite
+ " Has been added to Hostel " + hostelName;
}
Run Code Online (Sandbox Code Playgroud)
但是我得到编译时错误;
房间很抽象; 无法实例化
我知道抽象类无法实例化,但添加房间的最佳方法是什么?
我喜欢这样一个事实:Go并没有给我百万种方法来做简单的事情 - 借用Python的Zen,"应该有一个 - 最好只有一个 - 显而易见的方法."
但是,我不清楚实例化类型的首选/惯用方法.基本类型很简单:
n := 0
t := 1.5
str := "Hello"
Run Code Online (Sandbox Code Playgroud)
但是结构呢?以下是等效的,如果是,哪个是首选的,为什么?
var f Foo
f := Foo{}
Run Code Online (Sandbox Code Playgroud)
切片怎么样?我可以做var xs []int,xs := []int{}或者xs := make([]int),但我认为第一种选择(与结构相对)与其他选项不同?我认为这也适用于地图.
有了指针,我听说new应该避免.这是一个很好的建议,如果是的话,什么才算是有效的用法new?
我意识到这可能部分是风格问题,但在任何情况下,选择特定风格的理由都会有所帮助.
我尝试以下代码检查模板是否在未评估的上下文中实例化:
#include "foo.h"
template <typename T = int>
constexpr auto f(int)
// from declaration, foo(std::declval<T>()) is allowed.
// Even if definition would produce errors if instantiated
-> decltype(foo(std::declval<T>()), void(), 42)
{
return 42;
}
static_assert(f(0) == 42);
Run Code Online (Sandbox Code Playgroud)
与foo作为模板功能:(没有错误)
template <typename ...Ts>
void foo(Ts... args)
{
static_assert(sizeof...(Ts) == 42, "!");
((args += ""), ...);
}
Run Code Online (Sandbox Code Playgroud)
与foo定期函子:(没有错误)
struct Foo
{
template <typename ...Ts>
void operator ()(Ts... args) const
{
static_assert(sizeof...(args) == 42, "!");
((args += ""), ...); …Run Code Online (Sandbox Code Playgroud) 在WPF MvvmFoundation之后,将View与ViewModel链接有许多选择,如http://www.paulstovell.com/mvvm-instantiation-approaches中所述.
但是,他们的示例没有关于如何将ViewModel与Model链接.
传统上我首先创建模型,然后创建一个或多个渲染它的视图.似乎MVVM推动人们创建View,它创建了ViewModel,它创建了Model.我希望情况并非如此,因为使用各种ModelView连接复杂的商业模式可能很难.
如何在MVVM中实例化业务模型类并将它们与ViewModel 链接?
我有能力在编译时扩展一个类,但我需要能够在运行时使用已经实例化的超类的实例创建该子类的实例.
这在理论上应该是可能的,因为超类构造函数已经在子类构造函数之前被调用.
我无法充分访问该程序以将实例化更改为我的子类,也无法中断原始实例化.
用例:存在类X的现有实例数组.我的代码在之后加载.我需要覆盖其中一个实例X的一个方法,我的加载子类Y扩展X.父程序只通过该数组访问对象,所以我想用我的Y实例替换该数组元素,但它需要表现得好像它最初被实例化到该数组中.我不能只包含超类实例和转发调用,并且重新实现超类也很困难.
我希望更清楚.
给定模板元程序(TMP),C++编译器是否会生成计算实例化类数的构建统计信息?或者有没有其他方法可以自动获取此号码?因此对于例如对立的因子
#include <iostream>
template<int N> struct fact { enum { value = N * fact<N-1>::value }; };
template<> struct fact<1> { enum { value = 1 }; };
int main()
{
const int x = fact<3>::value;
std::cout << x << "\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想回到数字3(因为事实<3>,事实<2>,事实<1>被实例化).这个例子当然是微不足道的,但每当你开始使用例如Boost.MPL时,编译时间真的会爆炸,我想知道有多少是由于隐藏的类实例化造成的.我的问题主要是针对Visual C++,但是gcc的答案也会受到赞赏.
编辑:我目前非常脆弱的Visual C++方法是从Stephan T. Lavavej的视频/d1reportAllClassLayout 之一添加编译开关,并在输出文件上执行grep +字数,但它(a)极大地增加了编译时间,并且(b)正则表达式很难100%正确.
c++ templates counter instantiation template-meta-programming
我一直在研究一种实例化方法,它允许我将各种类似的类打包到一个外部类中.然后,我可以通过将该类型的名称传递给构造函数来实例化每个唯一的类类型.经过大量的研究和错误,这就是我想出的.我留下了一个错误,以证明我的问题.
import java.lang.reflect.Constructor;
public class NewTest
{
public static void main(String[] args)
{
try
{
Class toRun = Class.forName("NewTest$" + args[0]);
toRun.getConstructor().newInstance();
}
catch(Exception ex)
{
ex.printStackTrace();
System.out.println(ex.getMessage());
}
}
public NewTest(){}
private class one //Does not instantiate
{
public one()
{
System.out.println("Test1");
}
}
private static class two //Instantiates okay
{
public two()
{
System.out.println("Test2");
}
}
}
Run Code Online (Sandbox Code Playgroud)
按照我的意图编译此代码并java NewTest two在输出中运行结果Test2.
运行java NewTest one结果
java.lang.NoSuchMethodException: NewTest$one.<init>()
at java.lang.Class.getConstructor(Unknown Source)
at java.lang.Class.getConstructor(Unknown Source)
at …Run Code Online (Sandbox Code Playgroud) 我想实现类似"registerClassForAction"的东西.为此,我定义了一个协议:
@objc protocol TestProt {
func testMe() -> String
}
Run Code Online (Sandbox Code Playgroud)
我们来做一个班级宣言:
class TestClass: NSObject, TestProt {
func testMe() -> String {
return "test"
}
}
Run Code Online (Sandbox Code Playgroud)
我定义了在另一个类中注册对象的函数:
func registerClassForAction(aClass: AnyClass) { ... }
Run Code Online (Sandbox Code Playgroud)
切换到REPL,我将模拟寄存器方法:
let aClass: AnyClass = TestClass.classForCoder() //or .self
let tClass = aClass as NSObject.Type
let tInst = tClass() as TestProt
tInst.testMe()
Run Code Online (Sandbox Code Playgroud)
这当前有效,但有另一种实例化tClass的方法,除了
let tClass = aClass as NSObject.Type
Run Code Online (Sandbox Code Playgroud)
问的原因,我想探索摆脱NSObject的机会所以我的TestClass不会继承NSObject.考虑了委托,但我想控制tInst的生命周期,并能够在特定时间点解除它.
谢谢你的帮助
罗恩
template<typename T>
struct a
{
using type = int;
typename T::type i;
};
template<typename T, typename = a<T>>
void f1(T) {}
template<typename T, typename = typename a<T>::type>
void f2(T) {}
int main()
{
f1<int>(1); // ok
f2<int>(1); // error
return 0;
}
Run Code Online (Sandbox Code Playgroud)
实例化a<int>应该是错误,因为它int::type是非法的.但似乎f1<int>不能引起实例化a<T>,但f2<int>可以.什么原因?
据我了解,c ++模板通过为每种所需的类型编译一个单独的类或函数来工作。对于只需要少数几种不同类型/参数调用的类或函数来说,这似乎是合乎逻辑的,但是std::array似乎这可能导致同一类被编译成数百种不同版本。
我了解std::array过C样式数组的优点,但是如果我的上述假设正确的话,使用前者似乎会产生比后者更大的二进制大小。
例如,如果说在一个大型程序中,我们最终在整个代码中使用了99个大小不同的数组,那么我们实际上就有:
int arr[1] = { ... }
int arr[2] = { ... }
int arr[...] = { ... }
int arr[99] = { ... }
int arr[100] = { ... }
Run Code Online (Sandbox Code Playgroud)
要么
std::array<int, 1> arr = { ... }
std::array<int, 2> arr = { ... }
std::array<int, ...> arr = { ... }
std::array<int, 99> arr = { ... }
std::array<int, 100> arr = { ... }
Run Code Online (Sandbox Code Playgroud)
该std::array示例是否将整个类及其所有函数编译为二进制文件99次而结束?
instantiation ×10
c++ ×4
templates ×4
java ×3
counter ×1
declaration ×1
go ×1
idiomatic ×1
inheritance ×1
lambda ×1
model ×1
mvvm ×1
protocols ×1
reflection ×1
runtime ×1
swift ×1
types ×1
wpf ×1